2016-09-05 6 views
6

Ich habe eine Tabelle mit einer unbekannten Anzahl von Spalten (und auch unbekannte Spaltennamen) mit verschiedenen Arten von Daten (kann alles von Bit bis Nvarchar oder Datetime) wie folgt sein:SQL-Anzahl leere Zellen in unbekannter Anzahl von Spalten

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

ich brauche eine Abfrage, die alle NULL und leere Zellen auf jeder Spalte zählt und gibt das Ergebnis wie folgt aus:

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

ich verstehe, dass ich dynamische Abfragen und UNPIVOT, aber meine SQL-Kenntnisse verwenden ist nicht annähernd das!

How to count all NULL values in a table? scheint nicht, wie es ist MySQL Zusammenhang mit der Arbeit, nicht MS SQL

+0

Mögliche Duplikat von [Wie alle NULL-Werte in einer Tabelle zählen?] (Http://stackoverflow.com/questions/2295318/how-to-count-all -null-Werte-in-einer-Tabelle) – webmaster

+1

@webmaster, Ihr * mögliches Duplikat * ist für 'MySQL', während dies gegen' SQL Server' läuft – Shnugo

+0

Ja verstanden spät, vielen Dank. – webmaster

Antwort

3

Sie können diese dynamischen SQL-Code ausprobieren:

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

Ich musste die zweite dynamische Abfrage so bearbeiten, dass sie Nulls enthielt (da ich Ergebnisse in einem einzelnen Tabellenformat benötigte), aber es funktionierte wie ein Zauber, danke! – espressionist

0

EDIT: Diese Antwort für MySQL ist (nicht sorgfältig zuerst gelesen hat)

Von this answer

, ich denke, das Ergebnis wird Ihr alle "null" Zellen zählen:

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

Vielen Dank für die schnelle Antwort, aber Ihre Antwort bezieht sich auf MySQL und scheint nicht in MSSQL – espressionist

+0

zu funktionieren. Ah, tut mir leid, ich habe nur falsch geschätzt. Danke für die Warnung. – webmaster

1

Hier ist eine Methode zum Zurückgeben der Felder mit Null oder leere Werte aus einer Tabelle.
Über das Generieren und Ausführen einer dynamischen Abfrage mit einem Unpivot.
auf einem SQL Server getestet 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

Ich habe es selbst getestet, funktioniert gut mit NULLs, aber ich muss auch die leeren Zellen enthalten! – espressionist

+0

@espressionist Tatsächlich habe ich das übersehen. Jetzt behoben. Jetzt zählt es auch diejenigen mit einem leeren Text oder wenn es nur Leerzeichen enthält. Ich habe eine RTRIM nur für den Fall hinzugefügt, aber während des Testens entdeckte ich, dass die LEN eines VARCHAR mit nur Leerzeichen auch gleich 0 ist. Eine interessante kleine T-SQL-Quirck. – LukStorms

Verwandte Themen