如何在通过sys.partitions统计行数时添加WHERE筛选条件?
SQL统计行数问题解答
一、能否通过sys.partitions统计Department='HR'的行数?
不行。sys.partitions中的rows字段存储的是整个表或索引的总行数统计值,不记录行级的筛选条件信息,没法直接在这个视图里添加列筛选逻辑。你尝试的object_id('MyTable' where Department ='HR')是语法错误,object_id()函数仅能接收表名参数,不能附加where条件。
可行方案:
- 直接查询原表(推荐,结果准确)
SELECT COUNT(*) FROM MyTable WHERE Department = 'HR';
- 利用统计信息获取近似值(仅作参考,需确保统计信息更新)
-- 先更新统计信息,保证数据准确性 UPDATE STATISTICS MyTable; -- 查询近似行数 SELECT SUM(s.range_rows + s.equal_rows) AS approximate_row_count FROM sys.stats st JOIN sys.stats_columns sc ON st.object_id = sc.object_id AND st.stats_id = sc.stats_id JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id CROSS APPLY sys.dm_db_stats_histogram(st.object_id, st.stats_id) s WHERE st.object_id = OBJECT_ID('MyTable') AND c.name = 'Department' AND s.range_high_key = 'HR';
注意:该方法返回的是近似值,若统计信息未及时更新,结果会有偏差。
二、关联sys.partitions与原表结果异常的解决
你的关联逻辑join mytable t on p.object_id = object_id('mytable ')存在错误:object_id('mytable ')是固定的表ID值,这会导致sys.partitions的每一行都与MyTable的所有行做笛卡尔积,最终sum(p.rows)的结果是「表总行数 × 表总行数」,自然远超出预期。
正确处理方式:
- 直接查询原表(结果准确)
SELECT COUNT(*) FROM mytable WHERE YEAR(creationdate) = 2023;
- 若表为日期分区表,可通过分区统计行数
仅当MyTable按creationdate字段做了分区时适用:
SELECT SUM(p.rows) AS row_count FROM sys.partitions p JOIN sys.partition_schemes ps ON p.partition_scheme_id = ps.data_space_id JOIN sys.partition_functions pf ON ps.function_id = pf.function_id JOIN sys.partition_range_values prv ON pf.function_id = prv.function_id AND p.partition_number = prv.boundary_id WHERE p.object_id = OBJECT_ID('mytable') AND p.index_id IN (0,1) AND YEAR(CAST(prv.value AS DATE)) = 2023;
内容的提问来源于stack exchange,提问作者Melissa
相关产品推荐
相关产品推荐

