Oracle与SQL server均是该种情况。
发现问题
工作时,在生产环境中检查供应商、客户数据时,发现使用GROUP BY查询后的数量和COUNT(字段名称)查询的数量不一致:
--视图如下
CREATE OR REPLACE VIEW FSSCGYS1 AS
SELECT
MAX(ID) AS ID, MAX(SUPID) AS SUPID, MAX(SUPIS) AS SUPIS, MAX(SUPISDEC) AS SUPISDEC,
MAX(SUPNAME) AS SUPNAME, OWNCODE
FROM FSSCGYSZSJ1 GROUP BY OWNCODE;
--查询结果
SELECT COUNT(*) FROM FSSCGYSZSJ1 --2833 不过滤重复行2833
SELECT COUNT(*) FROM FSSCGYS1;--2823
SELECT COUNT(DISTINCT OWNCODE) FROM FSSCGYSZSJ1;--2822
寻找原因
后根据查询资料和进一步测试,发现是由于COUNT()中的字段导致的,如果小括号里写的列,值有NULL就会这样,值为NULL不统计行数。
--生产环境中的表查询值为NULL的行数
SELECT COUNT(OWNCODE) FROM FSSCGYSZSJ1 WHERE OWNCODE IS NULL;--0
--测试表
CREATE TABLE TEST
(
ID VARCHAR(50) NOT NULL,
NAME VARCHAR(50) NULL
);
INSERT INTO TEST (ID) VALUES('001');
分别在 Oracle 与 SQL server 中查询,结果均一致
SELECT COUNT(*) FROM TEST;--1
SELECT COUNT(NAME) FROM TEST;--0
总结
1、COUNT(1)和COUNT(*)结果一致,包含NULL值的行;
2、COUNT(字段)结果不计算NULL值;
3、COUNT(NULL)结果恒为0;
4、GROUP BY(字段) 过滤后的数据包含该字段为NULL的行。
问题环境
--Oracle
SELECT * FROM V$VERSION;
BANNER CON_ID
1 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0
2 PL/SQL Release 12.2.0.1.0 - Production 0
3 "CORE 12.2.0.1.0 Production" 0
4 TNS for 64-bit Windows: Version 12.2.0.1.0 - Production 0
5 NLSRTL Version 12.2.0.1.0 - Production 0
--SQL server
SELECT @@VERSION;
Microsoft SQL Server 2014 - 12.0.2269.0 (Intel X86)
Jun 10 2015 03:19:53
Copyright (c) Microsoft Corporation
Enterprise Edition on Windows NT 6.3 <X64> (Build 17134: ) (WOW64)