如果表中有未知列名,如何列出所有列名和非空(NULL
或空字符串<的行数/ em>)该列中的值?
小例子:
Col1 | Col2 | Col3 | dkasldk | dD? d3# !(
1 | | 2 | |
| 2 | d | ddd939 |
f | f | 84 | |
应该屈服:
Column Name | Values
Col1 | 2
Col2 | 2
Col3 | 3
dkasldk | 1
dD? d3# !( | 0
我已经尝试过使用INFORMATION_SCHEMA.COLUMNS
并创建动态SQL查询,但无济于事:
select N'select c.COLUMN_NAME,
(select sum(case when p.' + QUOTENAME(c.COLUMN_NAME) + ' != '''' then 1 else 0 end) from [Produkte] p) [Produkte]
from INFORMATION_SCHEMA.COLUMNS c
where c.TABLE_NAME = ''Produkte'' and c.COLUMN_NAME = ''' + c.COLUMN_NAME + '''' select_statement
from INFORMATION_SCHEMA.COLUMNS c
where c.TABLE_NAME = 'Produkte'
我无法完全理解如何结合动态列名和计算空值的两个问题(我确实找到了自己的解决方案,但不是组合) ...
答案 0 :(得分:1)
你可以使用UNPIVOT做这样的事情。
DECLARE @TableName NVARCHAR(MAX) = N'Produkte',
@CountColumns NVARCHAR(MAX),
@Columns NVARCHAR(MAX),
@Sql NVARCHAR(MAX)
SELECT @CountColumns = COALESCE(@CountColumns + ',', '') + 'COUNT(NULLIF(' + QUOTENAME(c.COLUMN_NAME) + ','''')) AS ' + QUOTENAME(c.COLUMN_NAME),
@Columns = COALESCE(@Columns + ',', '') + QUOTENAME(c.COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.TABLE_NAME = @TableName
SET @SQL = 'SELECT [Column Name], [Values]
FROM (
SELECT '
+ @CountColumns + '
FROM ' + @TableName + '
) t
UNPIVOT (
[Values]
FOR [Column Name] IN (' + @Columns + ')
) up
'
EXEC(@SQL)
答案 1 :(得分:1)
您可以使用动态UNPIVOT
。
使用这些变量:
DECLARE @qry NVARCHAR(MAX)
DECLARE @cols NVARCHAR(MAX) = ''
您可以使用以下动态sql以适合UNPIVOT
操作的格式选择列名称:
SELECT @cols = STUFF((SELECT ',[' + c.COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.TABLE_NAME = 'Produkte'
FOR XML PATH('')), 1, 1, '')
最后使用@cols
构建查询:
SET @qry = 'SELECT t.Col, COUNT(*)
FROM (SELECT Val, Col
FROM Produkte
UNPIVOT (
Val FOR Col IN (' + @cols + ')) unpvt
) AS t
WHERE t.Val <> '''' OR t.Val IS NOT NULL
GROUP BY t.Col'
...并执行它以获得所需的结果:
EXEC(@qry)
答案 2 :(得分:1)
最终你所追求的SQL是这样的:
SELECT ColumnName, NonEmpty
FROM ( SELECT A = 1,
[Col1] = COUNT(CASE WHEN [Col1] <> '' THEN 1 END),
[Col2] = COUNT(CASE WHEN [Col2] <> '' THEN 1 END),
[Col3] = COUNT(CASE WHEN [Col3] <> '' THEN 1 END),
[dkasldk] = COUNT(CASE WHEN [dkasldk] <> '' THEN 1 END),
[dD? d3# !(] = COUNT(CASE WHEN [dD? d3# !(] <> '' THEN 1 END)
FROM #T
) AS t
UNPIVOT
( NonEmpty
FOR ColumnName IN ([Col1],[Col2],[Col3],[dkasldk],[dD? d3# !(])
) AS upvt;
UNPIVOT
将从
Col1 Col2 Col3
-------------------------
1 3 2
达到您需要的格式:
ColumnName NonEmpty
-------------------------
Col1 1
Col2 3
Col3 2
您可以使用以下内容动态构建:
-- SAMPLE DATA
USE TempDB;
CREATE TABLE #T
(
[Col1] VARCHAR(1),
[Col2] VARCHAR(1),
[Col3] VARCHAR(2),
[dkasldk] VARCHAR(6),
[dD? d3# !(] VARCHAR(1)
);
INSERT #T ([Col1], [Col2], [Col3], [dkasldk], [dD? d3# !(])
VALUES
('1', NULL, '2', NULL, ''),
('', '2', 'd', 'ddd939', NULL),
('f', 'f', '84', NULL, '');
DECLARE @TableName SYSNAME = '#T';
-- VALID INPUT TABLE
IF OBJECT_ID(@TableName, 'U') IS NULL
AND OBJECT_ID(@TableName, 'V') IS NULL
BEGIN
PRINT 'Invalid table or View';
RETURN
END
-- BUILD DYNAMIC SQL
DECLARE @SQL NVARCHAR(MAX) =
CONCAT('SELECT ColumnName, NonEmpty FROM (SELECT A = 1, ' ,
STUFF(( SELECT CONCAT(',',
QUOTENAME(name),
' = COUNT(CASE WHEN ',
QUOTENAME(Name),
' <> '''' THEN 1 END)')
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@TableName)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, ''),
' FROM ',
@TableName,
') AS t UNPIVOT (NonEmpty FOR ColumnName IN (',
STUFF(( SELECT CONCAT(',', QUOTENAME(name))
FROM sys.columns
WHERE [object_id] = OBJECT_ID(@TableName)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, ''),
')) AS upvt');
-- EXECUTE DYNAMIC SQL
EXECUTE sp_executesql @SQL;