SQL 查询对表 X 的所有字段动态 COUNT(FIELD)

标签 sql sql-server

这应该是一件很容易的事情,但它让我完全难住了。

您可以轻松地手动返回表中每个字段的计数,例如:

select count(FIELD1) from TABLE1   --42,706
select count(FIELD5) from TABLE1   --42,686
select count(FIELD9) from TABLE1   --2,918

如果您想以相同的方式查看几十个表,并且需要您提前知道字段的名称,那么这是缓慢且痛苦的。

拥有一个可以连接到任何数据库的脚本,只需为其提供一个表名称,它就会自动返回该表中每个字段的计数,这该有多方便?

似乎你可以完成一半的工作:

select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'TABLE1'

即使采用我的准系统方法(明确地击中一个字段而不是全部字段),也有一些缺陷:

declare @TABLENAME varchar(30), @FIELDNAME varchar(30)
set @TABLENAME = 'TABLE1'

set @FIELDNAME = (select top 1 COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @TABLENAME
and COLUMN_NAME = 'FIELD9')

select @FIELDNAME, count(@FIELDNAME) from TABLE1

结果是 42,706。回想一下上面的示例,FIELD9 仅包含 2,918 个值。

即使这不是问题,更动态的查询也会将最后一行替换为:

select @FIELDNAME, count(@FIELDNAME) from @TABLENAME

但是 SQL Server 返回:

Must declare the table variable "@TABLENAME".

因此我可以通过使用临时表重组查询来避免这种情况:

declare @FIELDNAME varchar(30)

set @FIELDNAME = (select top 1 COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'TABLE1'
and COLUMN_NAME = 'FIELD9')

if OBJECT_ID('TEMPDB..#TEMP1') is not null
    drop table #TEMP1

select *
into #TEMP1
from TABLE1  --still not exactly dynamic!

select @FIELDNAME, count(@FIELDNAME) from #TEMP1

但这仍然让我们回到最初的问题,即返回 42,706 而不是 2,918。

我正在运行 SQL Server 2008 R2,如果有什么区别的话。

最佳答案

您的查询:

SELECT @FIELDNAME, COUNT(@FIELDNAME) FROM TABLE1

不计算FIELD9@FIELDNAME被视为常量。这就像执行 COUNT(*)

你应该使用动态sql:

DECLARE @sql VARCHAR(MAX)

SET @sql = 'SELECT ''' + @fieldName + ''', COUNT([' + @fieldName + ']) FROM [' + @tableName + ']'

EXEC(@sql)

要获取所有列并将其返回到单个结果集中,而不使用临时表CURSOR:

DECLARE @sql NVARCHAR(MAX) = ''

SELECT @sql = @sql +
'SELECT ''' + COLUMN_NAME + ''' AS ColName, COUNT([' + COLUMN_NAME + ']) FROM [' + @tableName + ']' + CHAR(10) +
'UNION ALL' + CHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @tableName

SELECT @sql = LEFT(@sql, LEN(@sql) - 10)
EXEC(@sql)

关于SQL 查询对表 X 的所有字段动态 COUNT(FIELD),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29000957/

相关文章:

SQL查询子表汇总和泛化

sql - 使用 FOR JSON 时获取值数组而不是对象数组

SQL - 子查询(列名)

sql - 基于列匹配的增量计数器(postgres)

mysql - 我应该为长内容使用哪种数据类型?

c# - 在参赛者之间动态分配奖品

python - 将 Python 列表传递给 SQL Server 查询的 ORDER BY 子句

sql - TNS监听器错误

mysql - 表别名在嵌套子查询中未知

mysql - 根据另一个表中的信息有条件地从一个表中求和