我有一个单行数百列宽的查询。我想在 Excel 中操作数据,获得又高又窄的结果是我的目标。每列都是一个数据值,我不确定如何取消PIVOT,但这似乎是正确的使用语句。像这些例子这样的列有数百个:
declare @rwcnt int
select @rwcnt = count(1)
from dbo.table_name
select
sum(cast(case when ButchID is null then 1 else 0 end *100 as numeric(5,2)))/@rwcnt ButchID_null_prct
,sum(cast(case when PatID is null then 1 else 0 end *100 as numeric(5,2)))/@rwcnt PatID_null_prct
这些可以正确查找列中空值的数量。我需要添加一个虚拟列来取消透视吗?
任何帮助表示赞赏。
谢谢你
您不需要单独获取行数。
您可以使用
AVG
将其除以计数,如本例所示
DECLARE @demo TABLE
(
Col1 INT NULL,
Col2 INT NULL,
Col3 INT NULL
)
INSERT @demo
VALUES
(1,2,NULL),
(1,2,NULL),
(1,NULL,NULL);
select
avg((case when Col1 is null then 100.00 else 0 end)) Col1_null_prct
,avg((case when Col2 is null then 100.00 else 0 end)) Col2_null_prct
,avg((case when Col3 is null then 100.00 else 0 end)) Col3_null_prct
from @demo
至于如何取消透视,一种方法是列出所有列
WITH T AS
(
select
avg((case when Col1 is null then 100.00 else 0 end)) Col1_null_prct
,avg((case when Col2 is null then 100.00 else 0 end)) Col2_null_prct
,avg((case when Col3 is null then 100.00 else 0 end)) Col3_null_prct
from @demo
)
SELECT col, val
FROM T
UNPIVOT (val FOR col IN (Col1_null_prct, Col2_null_prct, Col3_null_prct)) U
另一种方法是通过 XML 来回传输
WITH T1 AS
(
select
avg((case when Col1 is null then 100.00 else 0 end)) Col1_null_prct
,avg((case when Col2 is null then 100.00 else 0 end)) Col2_null_prct
,avg((case when Col3 is null then 100.00 else 0 end)) Col3_null_prct
from @demo
)
SELECT col = n.value('local-name(.)', 'sysname'),
val = n.value('./text()[1]', 'numeric(5,2)')
FROM (SELECT * FROM T1 FOR XML PATH('row'), TYPE) T2(x)
CROSS APPLY x.nodes('row/*') n(n)