SQL 不聚合的数据透视

SQL Pivot without aggregation

我在转换 SQL 结果的列中的行时遇到问题。

我的结构是这样的:

GUID |物业名称 |属性值

abcd |专有名称 | cn=abcd...

abcd|中国 | cn= GROUP_

abcd|操作 |添加

1231 |专有名称| cn=123dd

1231 |中文| cn=ASDGRUOP

1231 |操作 |删除

可以有 n 个我以前不知道的属性名称,它们是动态的 - 我可以通过 SQL 获取它们,这不是问题所在。

我想要这样的结构: 图形标识符 |专有名称 |中国 |操作

abcd| cn=abcd...| cn= GROUP_ |添加

1231 | cn=123dd | cn=广告组 |删除

等等。

我得到的 Column-Headers SQL:

select @cols = STUFF (( SELECT DISTINCT '],[' + x.ParameterName  from ... and parametername in ('PropertyValue','DistinguishedName', 'Operation')
FOR XML PATH ('')),1,2,'') + ']'

我可以用 PIVOT-Function 做到这一点,但是因为我没有聚合,所以我无法得到正确的结果:

set @query = N'SELECT '+ @cols + ' FROM (
    SELECT x.parametervalue, x.parametername
    from ... and parametername in (''PropertyValue'',''DistinguishedName'', ''Operation'')
    ) a
    PIVOT (max(a.parametervalue) FOR ParameterName in ( ' + @cols + ')) as pv;' 
exec sp_executesql @query;

我得到以下结果:

GUID |专有名称 |中国 |操作 | ...其他属性

abcd | cn=abcd... | cn = GROUP_ |添加 |...

只有 1 个结果 - 没有更多。但是这个查询有 700 个结果,因为 MAX() 函数我只得到一个。如何在没有聚合的情况下获得 Pivot 以获得所有结果?

提前致谢!

这是动态 PIVOT 查询:

DECLARE @sql NVARCHAR(MAX),
        @cols NVARCHAR(MAX);

SELECT @cols = 
    STUFF((
        SELECT DISTINCT ',' + QUOTENAME(PropertyName) 
        FROM #tbl
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    , 1, 1, '')

SELECT @sql = 
'SELECT GUID, ' + @cols + '
FROM (
    SELECT
        GUID, PropertyName, PropertyValue
    FROM #tbl
) t
PIVOT
(
    MAX(PropertyValue)
    FOR PropertyName IN(' + @cols + ')
) p ';

PRINT (@sql);
EXEC (@sql);

ONLINE DEMO


另一种达到预期效果的方法是使用 dynamic crosstab:

DECLARE @sql NVARCHAR(MAX);

SELECT @sql =
'SELECT
    GUID' + CHAR(10) +
(SELECT DISTINCT
'   , MAX(CASE WHEN PropertyName = ''' + PropertyName + ''' THEN PropertyValue END) AS ' + QUOTENAME(PropertyName) + CHAR(10)
FROM #tbl
FOR XML PATH('')
) +
'FROM #tbl
GROUP BY GUID;';

PRINT (@sql);
EXEC (@sql);

ONLINE DEMO