T-SQL 动态枢轴无法正常工作
Posted
技术标签:
【中文标题】T-SQL 动态枢轴无法正常工作【英文标题】:T-SQL Dynamic Pivot not working correctly 【发布时间】:2022-01-12 13:20:16 【问题描述】:我在我们的一个维度表中有keys
和values
类型的数据结构
键和值列都是nvarchar(500)
我正在进行数据质量检查,以确保数据透视查询返回的数字与暗表中键的实际值数相匹配,这对于大多数键来说都很好。然而
对于某些键,数据透视查询返回的计数小于键值数据结构中的实际值数
例如,其中一个关键是教育,而价值观是
Education school
Education sixthform
Education Titulo de Bachiller
Education SQA Highers
...
...
当我运行数据透视查询 where Education is not null
时,返回的行数为 23
当我在 key = Education 的暗表上运行查询时,返回的行数为 128
我正在使用以下数据透视查询
IF OBJECT_ID('tempdb.#TempTable') IS NOT NULL
BEGIN
DROP TABLE #TempTable
END
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT DISTINCT
',' + QUOTENAME(c.[Key])
FROM dbo.DimTable c
FOR XML PATH(''),
TYPE
).value('.','NVARCHAR(MAX)'),1,1,'')
SET @query = CONVERT(NVARCHAR(MAX),' (SELECT OrganisationGuid, Total, ') + CONVERT(NVARCHAR(MAX),@cols)
+ CONVERT(NVARCHAR(MAX),'
into #TempTable
from
(
SELECT
OrganisationGuid,
Total,
[Key],
[Value]
FROM dbo.DimTable
) x
pivot
(
max([Value])
for [Key] in (') + CONVERT(NVARCHAR(MAX),@cols) + CONVERT(NVARCHAR(MAX),')
) p )
select * from #TempTable t where t.[Education] is not null order by t.[Education]
')
EXECUTE sp_executesql @Query
有一个列 uniqueID 对暗表中的每一行都是唯一的,如果我在数据透视查询中包含该列,则结果与实际暗表中的计数匹配。
我需要知道为什么数据透视查询为某些键而不是所有键返回的记录较少,以及当包含在数据透视查询中时,包含 uniqueID 列与总数有何不同
这是我的简单查询,用于识别任何特定键的行数
SELECT * FROM dbo.DimTable
WHERE [Key] = 'Education' order by [value]
【问题讨论】:
调试动态SQL最简单的方法是先PRINT
/SELECT
语句。然后,您可以先调试该 SQL,并在将解决方案传播到生成动态语句的 SQL 之前解决问题。通常您会发现问题非常简单,例如难以在文字字符串中停止的印刷错误、缺少空格/换行符或前导/尾随分隔符。花时间让非动态语句首先工作非常重要,好像这不起作用,动态语句将没有机会正常工作。
RE “我需要知道为什么数据透视查询返回的某些键记录较少”:如果您仔细观察,您会注意到 PIVOT
进行聚合,即 max([Value]) for [Key]
(注意 max( ) 函数)。如果您没有在结果集中包含“唯一组 ID”列,则数据透视将聚合作为一个组应用于所有记录。它的工作方式类似于常规的GROUP BY
子句。
感谢@Alex,这正是问题所在,我一直在阅读有关 pivot 工作原理的文章,如果没有 uniqueID,您是绝对正确的,它不会准确
感谢@Larnu,我打印了整个 sql,并且键没有问题,这与 Alex 在他的 cmets 中提到的分组有关
【参考方案1】:
DimTable 上的查询返回更多记录,因为您查询的是从列[Key]
示例:下面是 DimTable
当您获取Key
列等于“Education”的记录时,它会返回满足 where 子句的所有记录,而与 Value 列数据无关。
select * from DimTable where [Key] = 'Education' order by [Key]
-
在您的数据透视查询中,您将值“Education”按值转换为列
[Education]
,因此教育列包含值列的数据,当您检查数据透视查询时,教育为 NOT NULL,则返回 DimTable 的 Value 不为 null 的记录。
在education不为null的情况下透视查询结果:
因此,如果 Value 列中有任何 NULL 值,Pivot 查询可能包含比在 Education 上查询 DimTable 时更少的记录。
【讨论】:
我会为您制作屏幕截图的努力投票,但我很难理解文字解释。以上是关于T-SQL 动态枢轴无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章