0

我们有一个审计系统,它记录所有系统表中发生的所有更改。基本上,这就是 AuditLog 表的样子:

在此处输入图像描述

目前我正在创建几个 sql 视图来查询不同类型的信息。一切都很好,除了一点。如果您再次查看该图像,您会看到我有一个 SubscriptionMetadata 表,它是一个键值对表,具有 2 个字段(MetaName 和 MetaValue)。图像显示的是订阅有一个新的水印,其值为“许可副本:全名、公司、V...”。

在我看来,我需要的是将这两行转换为以下形式:

41 - Insert - SubscriptionMetadata - 2012-10-19 - 53DA4XXXXXX - Watermark -  Licensed copy: Fullname, Company, V...

我真的无法想象我怎么能做到或搜索它。

还有另一个问题(我认为),这些行总是按这个顺序出现:首先是 MetaName,然后是 MetaValue。这是知道它们相关的唯一方法。

请问你能帮帮我吗?

4

3 回答 3

1

虽然我看不到您的完整表结构,但您可以通过以下方式转换数据。这两种解决方案都将数据放在单独的列中:

;with data(id, [action], [type], [date], [col], metatype, value) as
(
    select 41, 'Insert', 'SubscriptionMetaData', '2012-10-19', '53DA4XXX','Metaname', 'Watermark'
    union all
    select 41, 'Insert', 'SubscriptionMetaData', '2012-10-19', '53DA4XXX','MetaValue', 'Licensed copy: Fullname, Company'
) 
select id, action, type, date, col,
    MAX(case when metatype = 'Metaname' then value end) Name,
    MAX(case when metatype = 'MetaValue' then value end) Value
from data
group by id, action, type, date, col

请参阅带有演示的 SQL Fiddle

或者您可以PIVOT在数据上使用 a 来获得相同的结果:

;with data(id, [action], [type], [date], [col], metatype, value) as
(
    select 41, 'Insert', 'SubscriptionMetaData', '2012-10-19', '53DA4XXX','Metaname', 'Watermark'
    union all
    select 41, 'Insert', 'SubscriptionMetaData', '2012-10-19', '53DA4XXX','MetaValue', 'Licensed copy: Fullname, Company'
) 
select *
from
(
    select id, [action], [type], [date], [col], metatype, value
    from data
) src
pivot
(
    max(value)
    for metatype in (Metaname, MetaValue)
) piv

请参阅带有演示的 SQL Fiddle

两者都产生相同的结果:

| ID | ACTION |                 TYPE |       DATE |      COL |      NAME |                            VALUE |
-------------------------------------------------------------------------------------------------------------
| 41 | Insert | SubscriptionMetaData | 2012-10-19 | 53DA4XXX | Watermark | Licensed copy: Fullname, Company |
于 2012-12-13T14:44:47.147 回答
0

您可以使用 coalesce 函数通过存储过程或标量值函数执行此操作,如下所示:

DECLARE @Results NVARCHAR(MAX);
DECLARE @Token NVARCHAR(5) = '-'; -- separator token
SELECT @Results = coalesce(@Results + @Token,'') + t.MetaValue from (select * from TableName where MetaName = 'SubscriptionMetadata') t;
RETURN @Results; -- variable containing the concatenated values
于 2012-12-13T14:48:21.393 回答
0

这是一个工作示例。请根据需要替换列名。Col3 = your string concatenating column.

SELECT t1.col1,t1.col2,
       NameValue =REPLACE( (SELECT col3 AS [data()]
           FROM mytable t2
           WHERE t2.col1 = t1.col1
           ORDER BY t2.col1
           FOR XML PATH('')
           ), ' ', ' : ')
FROM mytable t1
GROUP BY col1,col2 ;

--DATA
1 |  X |  Name
1 |  X |  Value

--RESULTS
1 |  X |  Name:Value --Name Value pair here

编辑:如果您不需要连接 (根据您的评论)

SELECT t1.col1, t1.col2, t1.col3 NameColumn, t2.col3 ValueColumn
FROM (SELECT * FROM myTable WHERE col3 = 'Watermark') t1 JOIN 
     (SELECT * FROM myTable WHERE NOT (col3 = 'Watermark')) t2 
     ON t1.col1 = t2.col1
于 2012-12-13T14:49:16.330 回答