查找整个数据库中table的每一列(不包括空值和空值)的记录数
Find the record count in each column (exclude blank and null values) of table in entire database
我想找到整个数据库中所有 table 的每一列的记录数。该计数必须排除该列的空行和空行。我尝试了以下代码,但它显示了 table.
的行数
select
db_name() DatabaseName,
s.name + '.' + o.name TableName, c.name ColumnName, sum(p.rows) RecordCount
from sys.indexes i inner join sys.partitions p
on i.[object_id] = p.[object_id] and i.index_id = p.index_id
inner join sys.objects o
on o.[object_id] = i.[object_id]
inner join sys.columns c
on o.[object_id] = c.[object_id]
inner join sys.schemas s
on o.[schema_id] = s.[schema_id]
where i.index_id < 2
--and s.name in ('dbo', 'your_other_schema')
and o.type = 'U'
group by s.name, o.name , c.name
order by s.name, o.name;
代码输出。
https://i.stack.imgur.com/kNNRZ.png
列 system_id 有 5767 行计数,而对象状态只有 2589 行计数(不包括空白值和空值)
所以我预计 OBJECTSTATE
列数为 2589,SYSTEM_ID
数为 5767
输出像
Table Column Count
Table1 Column1 50 (excluding null and blank row)
Table1 Column2 45 (excluding null and blank row)
Table2 Column1 100 (excluding null and blank row)
Table2 column2 69 (excluding null and blank row)
如文档所述here,sys.partitions.rows
“表示此分区中的近似行数。”
将 sys.partitions
加入 sys.objects
和 sys.columns
没有帮助,因为您仍然只有分区级别的 rows
。
也就是说,您正在查询数据库的元数据。这样做,您无法获得所需的计数。
您需要做的是对每个 table 执行查询以获取 table 列的计数。为一个特定的 table(例如 Table1
)执行此操作的查询可能是:
SELECT
-- col1 would be a string (varchar, char, etc.) column
count(nullif(col1, '')) as col1_count,
-- col2 would not be a string column
count(col2) as col2_count
FROM Table1
以上查询为您提供了一个结果集,其中每个原始列都包含一列,一行包含计数。您可以更改查询以使用 PIVOT
交换列和行,这将为您提供所需的结构。
要在 all table 中获得您想要的结果而无需手动操作,您可以使用原始查询(只需连接 sys.objects
和sys.columns
虽然)并使用 CURSOR
遍历该查询的结果。在这个循环中,您将为所有 table 生成查询作为字符串或一个带有一些 UNION ALL
的大查询字符串。然后必须使用 EXEC()
来执行这些 strings/this 字符串
示例:
DECLARE @MyQuery NVARCHAR(MAX)
SET @MyQuery = 'SELECT ... FROM Table1 UNION ALL SELECT ... FORM Table2 ...'
EXEC(@MyQuery)
我想找到整个数据库中所有 table 的每一列的记录数。该计数必须排除该列的空行和空行。我尝试了以下代码,但它显示了 table.
的行数select
db_name() DatabaseName,
s.name + '.' + o.name TableName, c.name ColumnName, sum(p.rows) RecordCount
from sys.indexes i inner join sys.partitions p
on i.[object_id] = p.[object_id] and i.index_id = p.index_id
inner join sys.objects o
on o.[object_id] = i.[object_id]
inner join sys.columns c
on o.[object_id] = c.[object_id]
inner join sys.schemas s
on o.[schema_id] = s.[schema_id]
where i.index_id < 2
--and s.name in ('dbo', 'your_other_schema')
and o.type = 'U'
group by s.name, o.name , c.name
order by s.name, o.name;
代码输出。
https://i.stack.imgur.com/kNNRZ.png
列 system_id 有 5767 行计数,而对象状态只有 2589 行计数(不包括空白值和空值)
所以我预计 OBJECTSTATE
列数为 2589,SYSTEM_ID
数为 5767
输出像
Table Column Count
Table1 Column1 50 (excluding null and blank row)
Table1 Column2 45 (excluding null and blank row)
Table2 Column1 100 (excluding null and blank row)
Table2 column2 69 (excluding null and blank row)
如文档所述here,sys.partitions.rows
“表示此分区中的近似行数。”
将 sys.partitions
加入 sys.objects
和 sys.columns
没有帮助,因为您仍然只有分区级别的 rows
。
也就是说,您正在查询数据库的元数据。这样做,您无法获得所需的计数。
您需要做的是对每个 table 执行查询以获取 table 列的计数。为一个特定的 table(例如 Table1
)执行此操作的查询可能是:
SELECT
-- col1 would be a string (varchar, char, etc.) column
count(nullif(col1, '')) as col1_count,
-- col2 would not be a string column
count(col2) as col2_count
FROM Table1
以上查询为您提供了一个结果集,其中每个原始列都包含一列,一行包含计数。您可以更改查询以使用 PIVOT
交换列和行,这将为您提供所需的结构。
要在 all table 中获得您想要的结果而无需手动操作,您可以使用原始查询(只需连接 sys.objects
和sys.columns
虽然)并使用 CURSOR
遍历该查询的结果。在这个循环中,您将为所有 table 生成查询作为字符串或一个带有一些 UNION ALL
的大查询字符串。然后必须使用 EXEC()
示例:
DECLARE @MyQuery NVARCHAR(MAX)
SET @MyQuery = 'SELECT ... FROM Table1 UNION ALL SELECT ... FORM Table2 ...'
EXEC(@MyQuery)