我加入了一个非常复杂的新项目。我们使用的是SQL Server 2012,并且拥有许多数据库(15+)。每个数据库中的每个表都有许多列(超过25 - 50) 每张表中有数千条记录。我想以最好的方式查看数据。但是,某些列有空值。我很难对每个表中存在的数据有所了解。
以下是我对样本数据的质疑。
Id |Column1 |Column2 | Column3 |Column4 |............|ColumnNth
1 | sam |*NULL* | 2 | *NULL* |............|mike
2 | jack |2014-02-03| *NULL* | 6 |............|*NULL*
3 | Rav | *NULL* | *NULL* | *NULL*|............|Jim
4 | *NULL* |2013-09-08| 7 | 922 |............|Rocky
5 | Tom |2014-10-08| 11 | 212 |............|Mary
...
...
等......
例如,下面是每行所有列的NULL计数。 [它不是数据库中的表。 " NULL计数"不是初始表的列。我只是为了便于解释而展示了这一点]
ID| Count of NULLs
1 | 5
2 |2
3 |10
4 |1
5 |0
6 | 1
7 | 2
8 | 3
...
...
等等。
现在我想在顶部查看数量较少的NULL数据。数据的顺序应按以下顺序排列。我只显示了ID的顺序,以便不再输入所有数据(列)。
ID
5
4
6
2
7
8
1
...
...
3
...
等......
输出说明:
1.行(ID = 5)的所有列的空值总数为零。这应该是第一个
2.行(ID = 4)和行(ID = 6)的所有列的空值总数为1。 ID = 4且ID = 6的行后面应该是ID = 5。
......等等......
在输出中,我不希望 NULL 被其他值替换为0或1或空值等。因此 NULL 应显示为如果它存在于初始表中,则它在输出中 我想查看所有列
请给我一个通用的存储过程或查询或一组查询。由于列数超过25-40,SP或查询应该可以在不指定列名的情况下工作。如果是存储过程,那么表名将是它的输入 我认为为此要求编写SP非常复杂。但我所问的是一个新的开发人员在他/她加入支持/维护项目时面临的实时情况,这个项目已经构建并包含大量数据的复杂庞大的数据库。感谢
答案 0 :(得分:1)
下面是一个示例,您可以根据实际表格的需要进行扩展。
SELECT
Id
, (SELECT COUNT(*)
FROM (VALUES(Column1), (Column2), (Column3), (Column4)) AS AllColumns(ColumnValue)
WHERE AllColumns.ColumnValue IS NULL) AS NullCount
FROM dbo.SampleTable
ORDER BY NullCount;
如果源表架构可能不同,则您需要使用动态SQL:
DECLARE @ColumnList nvarchar(MAX) =
(SELECT
STUFF((SELECT ',(' + name + ')'
FROM sys.columns
WHERE
object_id = OBJECT_ID(N'dbo.SampleTable')
AND name <> 'Id'
FOR XML PATH('')),1 ,1, '')
);
DECLARE @SQL nvarchar(MAX) = N'
SELECT
Id
, (SELECT COUNT(*)
FROM (VALUES' + @ColumnList + ') AS AllColumns(ColumnValue)
WHERE AllColumns.ColumnValue IS NULL) AS NullCount
FROM dbo.SampleTable
ORDER BY NullCount;';
EXEC sp_executesql @SQL;
编辑(添加说明和SQL 2005方法):
通过查询指定表中所有列的sys.columns目录视图来生成列列表,Id
除外(您可以根据需要使用相同的技术省略其他列)。每个包含的列都括在括号中,并用逗号分隔,以构建VALUES子句所需的字符串。 FOR XML
子句将此列表返回一个字符串,并使用STUFF函数删除无关的前导逗号,以便@ColumnList变量包含VALUES
子句所需的字符串。最后的SQL语句是通过连接SELECT
语句的其余部分构建的。
表值行构造函数(http://msdn.microsoft.com/en-us/library/dd776382.aspx)允许通过VALUES
子句指定一行或多行。这在最终查询中用于将每个源行的列列表转换为行,以便使用COUNT
聚合函数。
此处使用的技术(DECLARE语句中的行构造函数和初始化变量)是在SQL Server 2008中引入的,因此在早期的SQL Server版本中不起作用。下面的版本使用派生表而不是表值行构造函数,它将与SQL 2005一起使用。
DECLARE @ColumnList nvarchar(MAX) =
(SELECT
STUFF((SELECT ' UNION ALL SELECT ' + name
FROM sys.columns
WHERE
object_id = OBJECT_ID(N'dbo.SampleTable')
AND name <> 'Id'
FOR XML PATH('')),1 ,11, '')
);
DECLARE @SQL nvarchar(MAX) = N'
SELECT
Id
, (SELECT COUNT(*)
FROM (' + @ColumnList + ') AS AllColumns(ColumnValue)
WHERE AllColumns.ColumnValue IS NULL) AS NullCount
FROM dbo.SampleTable
ORDER BY NullCount;';
EXEC sp_executesql @SQL;
答案 1 :(得分:0)
没有纯SQL查询会计算表中的NULL
列,而没有说明列的名称。
如果您可以使用过程,则可以获取列名并通过从INFORMATION_SCHEMA.COLUMNS
获取列名并将它们连接起来来动态构建查询,如下面的查询(或其他替代声明here):< / p>
SELECT A.*,
( (CASE WHEN Column1 IS NULL THEN 1 ELSE 0 END)
+ (CASE WHEN Column2 IS NULL THEN 1 ELSE 0 END)
+ (CASE WHEN Column3 IS NULL THEN 1 ELSE 0 END)
.
.
.
+ (CASE WHEN ColumnN IS NULL THEN 1 ELSE 0 END)) AS NULL_CNT
FROM MYTABLE A
ORDER BY NULL_CNT DESC