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);
另一种达到预期效果的方法是使用 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);
我在转换 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);
另一种达到预期效果的方法是使用 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);