这应该是一件很容易的事情,但它让我完全难住了。
您可以轻松地手动返回表中每个字段的计数,例如:
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/