除了上述之外,一种可能的方法是使用PIVOT 和UNPIVOT 功能。
让我们首先创建表并根据问题插入数据:
/* Create table */
CREATE TABLE so_40957006 (
[name] VARCHAR(24),
[col1] VARCHAR(24),
[col2] VARCHAR(24),
[col3] VARCHAR(24),
[col4] VARCHAR(24)
)
/* Insert data */
INSERT INTO so_40957006 VALUES('abc', null, 'a@c.com', null, null)
INSERT INTO so_40957006 VALUES('bbc', null, null, null, null)
我们首先要做的是创建一个标识表,这样我们就可以唯一标识每一行数据并插入数据。
/* Create identity table */
CREATE TABLE so_40957006_id (
[lid] INT IDENTITY(1, 1),
[name] VARCHAR(24),
[col1] VARCHAR(24),
[col2] VARCHAR(24),
[col3] VARCHAR(24),
[col4] VARCHAR(24)
)
/* Insert data into table */
INSERT INTO so_40957006_id
SELECT
ISNULL([name], 1) AS [name]
,ISNULL([col1], 1) AS [col1]
,ISNULL([col2], 1) AS [col2]
,ISNULL([col3], 1) AS [col3]
,ISNULL([col4], 1) AS [col4]
FROM so_40957006
请注意,在此过程中,我们已使用 IsNull 将任何为空的列转换为值 1。该表现在如下所示。
lid name col1 col2 col3 col4
1 abc 1 a@c.com 1 1
2 bbc 1 1 1 1
有了这个,我们现在可以使用PIVOT 和UNPIVOT 来垂直化数据。例如,运行下面的查询
SELECT [lid], [cols], [val]
FROM
(SELECT [lid], [name], [col1], [col2], [col3], [col4]
FROM so_40957006_id) p
UNPIVOT
(val FOR cols IN
([name], [col1], [col2], [col3], [col4])
) AS unpvt
为您提供以下垂直输出:
lid cols val
1 name abc
1 col1 1
1 col2 a@c.com
1 col3 1
1 col4 1
2 name bbc
2 col1 1
2 col2 1
2 col3 1
2 col4 1
由于您要计算的值(即NULLs)的值为 1,您可以运行 GROUP BY + SUM 语句:
SELECT [lid], SUM(cast([val] as integer)) as CountNulls
FROM (
SELECT [lid], [cols], [val]
FROM
(SELECT [lid], [name], [col1], [col2], [col3], [col4]
FROM so_40957006_id) p
UNPIVOT
(val FOR cols IN
([name], [col1], [col2], [col3], [col4])
) AS unpvt
) a
WHERE ISNUMERIC([val]) = 1
GROUP BY [lid]
输出
lid CountNulls
1 3
2 4
使用[lid],您可以将JOIN 这个输出返回到原始表以生成您的结果集。