2016-09-05 32 views
6

我有一个表具有未知数量的列(以及未知的列名称)与不同类型的数据(可以是从位到nvarchar或日期时间的任何东西),如下所示:未知数的列中的SQL计数空单元格

ID | Col2 | Col3 | Customer | ..(etc).. 
1 | NULL | 0 | CustA |  
2 | valA | 1 | NULL | 
3 | valB | NULL | (empty) | 

我需要一个查询,其对每列的所有NULL和空细胞,结果这样的输出:

Column_Name | No_Of_Empty_And_Null_Cells | 
    Col2  |    1    | 
    Col3  |    1    | 
Customer |    2    | 
(etc...) |        | 

我明白,我必须使用动态查询和UNPIVOT,但我的SQL知识远远没有!

How to count all NULL values in a table?似乎 不工作,因为它是MySQL的关系,而不是MS SQL

+0

的可能的复制[如何计算表中的所有NULL值?(http://stackoverflow.com/questions/2295318/how-to-count-all -null-values-in-a-table) – webmaster

+1

@webmaster,你的*可能重复的*是针对'MySQL'而针对'SQL Server'运行的' – Shnugo

+0

很明白,非常感谢你。 – webmaster

回答

3

你可以试试这个动态的SQL代码了:

DECLARE @schema VARCHAR(100)='dbo'; 
DECLARE @tableName VARCHAR(100)='SomeTable'; 

DECLARE @DynamicSelect VARCHAR(MAX)= 
(
    STUFF((SELECT 'UNION SELECT ''' + COLUMN_NAME + ''' AS COLUMN_NAME' + 
     ', (SELECT COUNT(*) FROM ' + @schema + '.' + @tableName + ' WHERE [' + COLUMN_NAME + '] IS NULL) AS No_Of_Null_Cells ' 
     FROM INFORMATION_SCHEMA.COLUMNS AS c 
     WHERE [email protected] AND [email protected] AND c.IS_NULLABLE='YES' 
     FOR XML PATH('') 
     ),1,6,'') 
); 
exec (@DynamicSelect) 


DECLARE @DynamicSelect2 VARCHAR(MAX)= 
(
    STUFF((SELECT 'UNION SELECT ''' + COLUMN_NAME + ''' AS COLUMN_NAME' + 
     ', (SELECT COUNT(*) FROM ' + @schema + '.' + @tableName + ' WHERE LTRIM(RTRIM([' + COLUMN_NAME + '])) ='''') AS No_Of_Empty_Cells ' 
     FROM INFORMATION_SCHEMA.COLUMNS AS c 
     WHERE [email protected] AND [email protected] AND c.DATA_TYPE LIKE '%char%' 
     FOR XML PATH('') 
     ),1,6,'') 
); 
exec (@DynamicSelect2) 
+0

我不得不编辑第二个动态查询以包含空值(因为我需要单个表格格式的结果),但它的工作方式像一个魅力,谢谢! – espressionist

0

编辑:这个答案是MySQL(没仔细一开始读)

this answer,我觉得这结果将计算所有“空”细胞:

SET @db = 'your_database_name'; -- database 
SET @tb = 'your_table_name'; -- table 
SET @x = ''; -- will hold the column names with ASCII method applied to retrieve the number of the first char 
SET @numcolumns = 0; -- will hold the number of columns in the table 

-- figure out how many columns we have 
SELECT count(*) into @numcolumns FROM information_schema.columns where [email protected] and [email protected]; 

-- we have to prepare some query from all columns of the table 
SELECT group_concat(CONCAT('ASCII(',column_name,')')) into @x from information_schema.columns where [email protected] and [email protected]; 
-- after this query we have a variable separated with comma like 
-- ASCII(col1),ASCII(col2),ASCII(col3) 

-- we now generate a query to concat the columns using comma as separator (null values are omitted from concat) 
-- then figgure out how many times the comma is in that substring (this is done by using length(value)-length(replace(value,',','')) 
-- the number returned is how many non null columns we have in that column 
-- then we deduct the number from the known number of columns, calculated previously 
-- the +1 is added because there is no comma for single value 
SET @s = CONCAT('SELECT @numcolumns - (length(CONCAT_WS(\',\',', @x, '))-length(replace(CONCAT_WS(\',\',', @x, '),\',\',\'\')) + 1) FROM ',@db,'.',@tb,';'); 
PREPARE stmt FROM @s; 
EXECUTE stmt; 
-- after this execution we have returned for each row the number of null columns 
-- I will leave to you to add a sum() group call if you want to find the null values for the whole table 
DEALLOCATE PREPARE stmt; 
+0

感谢您的快速响应,但您的答案是指MySQL,似乎并没有在MSSQL – espressionist

+0

啊,所以很抱歉,我只是错误地估计。谢谢你的提醒。 – webmaster

1

以下是从表中返回空值或空值字段的方法。
通过生成并执行带有unpivot的动态查询。
测试了SQL Server上2014

DECLARE @SchemaName SYSNAME = 'YourDatabase'; 
DECLARE @TableName SYSNAME = 'YourTable'; 

DECLARE @SQL NVARCHAR(MAX); 

WITH COL AS (
    SELECT c.name 
    FROM sys.objects o 
    INNER JOIN sys.schemas s ON o.[schema_id] = s.[schema_id] 
    INNER JOIN sys.columns c ON o.[object_id] = c.[object_id] 
    WHERE o.[type] = 'U' 
     AND s.name = @SchemaName 
     AND o.name = @TableName 
     AND c.is_nullable = 1 
) 
SELECT @SQL = 'SELECT up.column_name, up.total_empty 
FROM (
SELECT ' + CHAR(13) + STUFF((
    SELECT CHAR(13) + ', ' + QUOTENAME(name) + ' = SUM(IIF(LEN(RTRIM(' + QUOTENAME(name) + '))>0,0,1))' 
    FROM COL 
    FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, ' ') + ' 
FROM ' + QUOTENAME(@SchemaName) + '.' + QUOTENAME(@TableName) + ') q 
UNPIVOT 
(total_empty for column_name in ('+ 
    STUFF((
    SELECT CHAR(13) + ', ' + QUOTENAME(name) FROM COL 
    FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, ' ') 
    +') 
) up where up.total_empty > 0 order by up.column_name'; 

--SELECT @SQL; 
EXEC sys.sp_executesql @SQL; 
+0

我自己测试过它,与NULLs很好地工作,但我需要包括空单元格以及! – espressionist

+0

@espressionist事实上,我忽略了这一点。现在修复。现在它也会计算那些空文本或只包含空格的文本。为了防万一,我添加了一个RTRIM,但在测试过程中,我发现只有空格的varchar的LEN也等于0.一个有趣的小T-SQL quirck。 – LukStorms

相关问题