T SQL 来自 table 的前 10 个 NULL 列列表
T SQL Top 10 list of NULL Columns from a table
我正在使用 SQL Server 2014。我有一个包含多列的 table。是否可以动态列出 table 中的前 10 列和百分比每列中的记录是 NULL?我不想对每个列名称进行硬编码。
所以结果集会是这样的:
Column Percent_Null
ABC 100
QWE 75
REW 65
TRW 50
我是从下面开始的,但是如何将其放入列表中?最终结果需要进入 table 进行报告。
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = STUFF((
SELECT ', CAST(SUM(CASE WHEN ' + Quotename(C.COLUMN_NAME) + ' IS NULL THEN 1 ELSE 0 END) * 100.00
/@TotalCount AS INT) AS [' + C.COLUMN_NAME + ' NULL %]
'
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE TABLE_NAME = 'tblMYTable'
AND TABLE_SCHEMA = 'dbo'
ORDER BY C.ORDINAL_POSITION
FOR XML PATH('')
,type
).value('.', 'nvarchar(max)'), 1, 2, '')
PRINT @SQL
布拉格,这很丑陋,但它似乎可以满足您的要求:
DECLARE @Table sysname = N'icp_yyclient',
@Schema sysname = N'dbo';
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
--First get a Count, which will be one column per column
SET @SQL = N'WITH Counts AS(' + @CRLF +
N' SELECT ' +
STUFF((SELECT N',' + @CRLF +
N' (COUNT(CASE WHEN ' + QUOTENAME(C.[name]) + N' IS NULL THEN 1 END) * 1.) / COUNT(*) AS ' + QUOTENAME(c.[name] + N'_PercNULL')
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
WHERE s.name = @Schema
AND t.name = @Table
ORDER BY c.column_id
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,14,N'') + @CRLF +
N' FROM ' + QUOTENAME(@Schema) + N'.' + QUOTENAME(@Table) + N')' + @CRLF +
--Now that we have a COUNT of column, we need to unpivot the data
N'SELECT TOP(10) V.*' + @CRLF +
N'FROM Counts C' + @CRLF +
N' CROSS APPLY(VALUES' +
STUFF((SELECT N',' + @CRLF +
N' (N' + QUOTENAME(C.[name],'''') + N', C.' + QUOTENAME(c.[name] + N'_PercNULL') + N')'
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
WHERE s.name = @Schema
AND t.name = @Table
ORDER BY c.column_id
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,26,N'') + N')V(ColumnName,ColumnPercNULL)' + @CRLF +
N'ORDER BY V.ColumnPercNULL DESC;';
--Uncommon to see the "mess". I strongly suggest ensuring you have retain CR/LF on in SSMS
--SELECT @SQL; --PRINT is limited to 4,000 characters, so probably too small.
EXEC sp_executesql @SQL;
对于 table 我有,(称为 Asset
)这会创建以下语句:
WITH Counts AS(
SELECT (COUNT(CASE WHEN [AssetID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [AssetID_PercNULL],
(COUNT(CASE WHEN [AssetName] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [AssetName_PercNULL],
(COUNT(CASE WHEN [TypeID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [TypeID_PercNULL],
(COUNT(CASE WHEN [SerialNumber] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [SerialNumber_PercNULL],
(COUNT(CASE WHEN [BarcodeNumber] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [BarcodeNumber_PercNULL],
(COUNT(CASE WHEN [Manufacturer] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [Manufacturer_PercNULL],
(COUNT(CASE WHEN [Model] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [Model_PercNULL],
(COUNT(CASE WHEN [LocationID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [LocationID_PercNULL],
(COUNT(CASE WHEN [IPAddress] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [IPAddress_PercNULL],
(COUNT(CASE WHEN [PurchaseDate] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [PurchaseDate_PercNULL],
(COUNT(CASE WHEN [SetupDate] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [SetupDate_PercNULL],
(COUNT(CASE WHEN [DecommissionDate] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DecommissionDate_PercNULL],
(COUNT(CASE WHEN [ReasonID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [ReasonID_PercNULL],
(COUNT(CASE WHEN [DecommissionBy] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DecommissionBy_PercNULL],
(COUNT(CASE WHEN [InvoiceID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [InvoiceID_PercNULL],
(COUNT(CASE WHEN [IsVirtual] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [IsVirtual_PercNULL],
(COUNT(CASE WHEN [HostAssetID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [HostAssetID_PercNULL],
(COUNT(CASE WHEN [DestroyDate] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DestroyDate_PercNULL],
(COUNT(CASE WHEN [DestroyID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DestroyID_PercNULL],
(COUNT(CASE WHEN [DestroyedBy] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DestroyedBy_PercNULL],
(COUNT(CASE WHEN [ValueExVAT] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [ValueExVAT_PercNULL],
(COUNT(CASE WHEN [VATValue] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [VATValue_PercNULL],
(COUNT(CASE WHEN [ValueIncVAT] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [ValueIncVAT_PercNULL]
FROM [app].[Asset])
SELECT TOP(10) V.*
FROM Counts C
CROSS APPLY(VALUES(N'AssetID', C.[AssetID_PercNULL]),
(N'AssetName', C.[AssetName_PercNULL]),
(N'TypeID', C.[TypeID_PercNULL]),
(N'SerialNumber', C.[SerialNumber_PercNULL]),
(N'BarcodeNumber', C.[BarcodeNumber_PercNULL]),
(N'Manufacturer', C.[Manufacturer_PercNULL]),
(N'Model', C.[Model_PercNULL]),
(N'LocationID', C.[LocationID_PercNULL]),
(N'IPAddress', C.[IPAddress_PercNULL]),
(N'PurchaseDate', C.[PurchaseDate_PercNULL]),
(N'SetupDate', C.[SetupDate_PercNULL]),
(N'DecommissionDate', C.[DecommissionDate_PercNULL]),
(N'ReasonID', C.[ReasonID_PercNULL]),
(N'DecommissionBy', C.[DecommissionBy_PercNULL]),
(N'InvoiceID', C.[InvoiceID_PercNULL]),
(N'IsVirtual', C.[IsVirtual_PercNULL]),
(N'HostAssetID', C.[HostAssetID_PercNULL]),
(N'DestroyDate', C.[DestroyDate_PercNULL]),
(N'DestroyID', C.[DestroyID_PercNULL]),
(N'DestroyedBy', C.[DestroyedBy_PercNULL]),
(N'ValueExVAT', C.[ValueExVAT_PercNULL]),
(N'VATValue', C.[VATValue_PercNULL]),
(N'ValueIncVAT', C.[ValueIncVAT_PercNULL]))V(ColumnName,ColumnPercNULL)
ORDER BY V.ColumnPercNULL DESC;
这应该能让您深入了解它是如何得出结果的。
另一种方式,使用逆轴:
DECLARE @SCHEMANAME NVARCHAR(100) = 'dbo'
DECLARE @TABLENAME NVARCHAR(100) = 'your_table_name'
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = 'SELECT TOP (10) * FROM (SELECT '+
STUFF (
(
SELECT ', CAST(SUM(CASE WHEN ' + Quotename(C.COLUMN_NAME) + ' IS NULL THEN 1 ELSE 0 END) * 100.00/COUNT(*) AS INT) AS ' + QUOTENAME(C.COLUMN_NAME, '"') + CHAR(13)
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE TABLE_NAME = @TABLENAME
AND TABLE_SCHEMA = @SCHEMANAME
ORDER BY C.ORDINAL_POSITION
FOR XML PATH(''),type
).value('.', 'nvarchar(max)'),
1, 2, ''
)+' FROM '+QUOTENAME(@SCHEMANAME)+'.'+QUOTENAME(@TABLENAME)+') V1 UNPIVOT (NullsPerc FOR ColumnName IN ('+
STUFF (
(
SELECT ', '+ Quotename(C.COLUMN_NAME,'"') + CHAR(13)
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE TABLE_NAME = @TABLENAME
AND TABLE_SCHEMA = @SCHEMANAME
ORDER BY C.ORDINAL_POSITION
FOR XML PATH(''),type
).value('.', 'nvarchar(max)'),
1, 2, ''
)+
')) AS UPVT
ORDER BY NULLSPERC DESC'
SELECT @SQL
我正在使用 SQL Server 2014。我有一个包含多列的 table。是否可以动态列出 table 中的前 10 列和百分比每列中的记录是 NULL?我不想对每个列名称进行硬编码。
所以结果集会是这样的:
Column Percent_Null
ABC 100
QWE 75
REW 65
TRW 50
我是从下面开始的,但是如何将其放入列表中?最终结果需要进入 table 进行报告。
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = STUFF((
SELECT ', CAST(SUM(CASE WHEN ' + Quotename(C.COLUMN_NAME) + ' IS NULL THEN 1 ELSE 0 END) * 100.00
/@TotalCount AS INT) AS [' + C.COLUMN_NAME + ' NULL %]
'
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE TABLE_NAME = 'tblMYTable'
AND TABLE_SCHEMA = 'dbo'
ORDER BY C.ORDINAL_POSITION
FOR XML PATH('')
,type
).value('.', 'nvarchar(max)'), 1, 2, '')
PRINT @SQL
布拉格,这很丑陋,但它似乎可以满足您的要求:
DECLARE @Table sysname = N'icp_yyclient',
@Schema sysname = N'dbo';
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
--First get a Count, which will be one column per column
SET @SQL = N'WITH Counts AS(' + @CRLF +
N' SELECT ' +
STUFF((SELECT N',' + @CRLF +
N' (COUNT(CASE WHEN ' + QUOTENAME(C.[name]) + N' IS NULL THEN 1 END) * 1.) / COUNT(*) AS ' + QUOTENAME(c.[name] + N'_PercNULL')
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
WHERE s.name = @Schema
AND t.name = @Table
ORDER BY c.column_id
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,14,N'') + @CRLF +
N' FROM ' + QUOTENAME(@Schema) + N'.' + QUOTENAME(@Table) + N')' + @CRLF +
--Now that we have a COUNT of column, we need to unpivot the data
N'SELECT TOP(10) V.*' + @CRLF +
N'FROM Counts C' + @CRLF +
N' CROSS APPLY(VALUES' +
STUFF((SELECT N',' + @CRLF +
N' (N' + QUOTENAME(C.[name],'''') + N', C.' + QUOTENAME(c.[name] + N'_PercNULL') + N')'
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
WHERE s.name = @Schema
AND t.name = @Table
ORDER BY c.column_id
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,26,N'') + N')V(ColumnName,ColumnPercNULL)' + @CRLF +
N'ORDER BY V.ColumnPercNULL DESC;';
--Uncommon to see the "mess". I strongly suggest ensuring you have retain CR/LF on in SSMS
--SELECT @SQL; --PRINT is limited to 4,000 characters, so probably too small.
EXEC sp_executesql @SQL;
对于 table 我有,(称为 Asset
)这会创建以下语句:
WITH Counts AS(
SELECT (COUNT(CASE WHEN [AssetID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [AssetID_PercNULL],
(COUNT(CASE WHEN [AssetName] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [AssetName_PercNULL],
(COUNT(CASE WHEN [TypeID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [TypeID_PercNULL],
(COUNT(CASE WHEN [SerialNumber] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [SerialNumber_PercNULL],
(COUNT(CASE WHEN [BarcodeNumber] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [BarcodeNumber_PercNULL],
(COUNT(CASE WHEN [Manufacturer] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [Manufacturer_PercNULL],
(COUNT(CASE WHEN [Model] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [Model_PercNULL],
(COUNT(CASE WHEN [LocationID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [LocationID_PercNULL],
(COUNT(CASE WHEN [IPAddress] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [IPAddress_PercNULL],
(COUNT(CASE WHEN [PurchaseDate] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [PurchaseDate_PercNULL],
(COUNT(CASE WHEN [SetupDate] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [SetupDate_PercNULL],
(COUNT(CASE WHEN [DecommissionDate] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DecommissionDate_PercNULL],
(COUNT(CASE WHEN [ReasonID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [ReasonID_PercNULL],
(COUNT(CASE WHEN [DecommissionBy] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DecommissionBy_PercNULL],
(COUNT(CASE WHEN [InvoiceID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [InvoiceID_PercNULL],
(COUNT(CASE WHEN [IsVirtual] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [IsVirtual_PercNULL],
(COUNT(CASE WHEN [HostAssetID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [HostAssetID_PercNULL],
(COUNT(CASE WHEN [DestroyDate] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DestroyDate_PercNULL],
(COUNT(CASE WHEN [DestroyID] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DestroyID_PercNULL],
(COUNT(CASE WHEN [DestroyedBy] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [DestroyedBy_PercNULL],
(COUNT(CASE WHEN [ValueExVAT] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [ValueExVAT_PercNULL],
(COUNT(CASE WHEN [VATValue] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [VATValue_PercNULL],
(COUNT(CASE WHEN [ValueIncVAT] IS NULL THEN 1 END) * 1.) / COUNT(*) AS [ValueIncVAT_PercNULL]
FROM [app].[Asset])
SELECT TOP(10) V.*
FROM Counts C
CROSS APPLY(VALUES(N'AssetID', C.[AssetID_PercNULL]),
(N'AssetName', C.[AssetName_PercNULL]),
(N'TypeID', C.[TypeID_PercNULL]),
(N'SerialNumber', C.[SerialNumber_PercNULL]),
(N'BarcodeNumber', C.[BarcodeNumber_PercNULL]),
(N'Manufacturer', C.[Manufacturer_PercNULL]),
(N'Model', C.[Model_PercNULL]),
(N'LocationID', C.[LocationID_PercNULL]),
(N'IPAddress', C.[IPAddress_PercNULL]),
(N'PurchaseDate', C.[PurchaseDate_PercNULL]),
(N'SetupDate', C.[SetupDate_PercNULL]),
(N'DecommissionDate', C.[DecommissionDate_PercNULL]),
(N'ReasonID', C.[ReasonID_PercNULL]),
(N'DecommissionBy', C.[DecommissionBy_PercNULL]),
(N'InvoiceID', C.[InvoiceID_PercNULL]),
(N'IsVirtual', C.[IsVirtual_PercNULL]),
(N'HostAssetID', C.[HostAssetID_PercNULL]),
(N'DestroyDate', C.[DestroyDate_PercNULL]),
(N'DestroyID', C.[DestroyID_PercNULL]),
(N'DestroyedBy', C.[DestroyedBy_PercNULL]),
(N'ValueExVAT', C.[ValueExVAT_PercNULL]),
(N'VATValue', C.[VATValue_PercNULL]),
(N'ValueIncVAT', C.[ValueIncVAT_PercNULL]))V(ColumnName,ColumnPercNULL)
ORDER BY V.ColumnPercNULL DESC;
这应该能让您深入了解它是如何得出结果的。
另一种方式,使用逆轴:
DECLARE @SCHEMANAME NVARCHAR(100) = 'dbo'
DECLARE @TABLENAME NVARCHAR(100) = 'your_table_name'
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = 'SELECT TOP (10) * FROM (SELECT '+
STUFF (
(
SELECT ', CAST(SUM(CASE WHEN ' + Quotename(C.COLUMN_NAME) + ' IS NULL THEN 1 ELSE 0 END) * 100.00/COUNT(*) AS INT) AS ' + QUOTENAME(C.COLUMN_NAME, '"') + CHAR(13)
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE TABLE_NAME = @TABLENAME
AND TABLE_SCHEMA = @SCHEMANAME
ORDER BY C.ORDINAL_POSITION
FOR XML PATH(''),type
).value('.', 'nvarchar(max)'),
1, 2, ''
)+' FROM '+QUOTENAME(@SCHEMANAME)+'.'+QUOTENAME(@TABLENAME)+') V1 UNPIVOT (NullsPerc FOR ColumnName IN ('+
STUFF (
(
SELECT ', '+ Quotename(C.COLUMN_NAME,'"') + CHAR(13)
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE TABLE_NAME = @TABLENAME
AND TABLE_SCHEMA = @SCHEMANAME
ORDER BY C.ORDINAL_POSITION
FOR XML PATH(''),type
).value('.', 'nvarchar(max)'),
1, 2, ''
)+
')) AS UPVT
ORDER BY NULLSPERC DESC'
SELECT @SQL