运行count(*)和count(*)组的SQL返回不同的行数

时间:2014-04-15 20:14:42

标签: sql sql-server

这很奇怪,假设我在SQL server中有一个名为dbo.internetquotes的表。

我希望获得一个月内的引号总数,并将其分解为一个名为quotetype的列。

我运行查询:

select count(*) from dbo.internetquotes
where quotedate between '2014/03/01' and '2014/04/01';

然后返回20k。

现在我运行查询

select count(*), quotetype from dbo.internetquotes
where quotedate between '2014/03/01' and '2014/04/01'
group by quotetype;

它返回每个类型的计数。但是,当我总结第二个查询的计数时,数字不等于20k(略小)。我的想法可能是列类型中有空值但是运行select * where quotetype = null会返回0行。

出现差异的原因是什么?

2 个答案:

答案 0 :(得分:0)

如果任何事情与聚合不匹配,只需考虑三个值 - TRUE,FALSE,UNKNOWN。

聚合时你可能会退出NULLS(UNKNOWN)。

另外,请使用>和<在处理日期时。

Bad habits to kick : mis-handling date / range queries

-- 1 - Skip nulls
select 
    count(*) as Total
from 
    dbo.internetquotes
where 
    quotedate >= '20140301' and 
    quotedate < '20140401' and
    quotetype is not null

-- 2 - Skip nulls
select 
    quotetype, count(*) as total
from 
    dbo.internetquotes
where 
    quotedate >= '20140301' and 
    quotedate < '20140401' and
    quotetype is not null
group by 
    quotetype;

这两个查询应该具有相同的计数。祝你好运。

只需使用Adventure Works并尝试这些查询

-- 31465
select count(*) from [Sales].[SalesOrderHeader]

-- Group by person 
select SalesPersonID, count(*) as total
into #temp
from [Sales].[SalesOrderHeader] 
group  by SalesPersonID

-- 18 rows for a total count of 31465
select sum(total) as grand from #temp

空值将被分组并显示为一行。我从不打折。但是日期问题可能会丢失数据。我支持这个!

答案 1 :(得分:0)

我想了一会儿,我认为你有重复的行或重复的引用。

你可以运行类似的东西:

select count(distinct quotedate) from dbo.internetquotes
where quotedate between '2014/03/01' and '2014/04/01';

与第二次查询的总和(计数)进行比较。