2016-09-05 35 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

相關問題