Sql server 是否消除来自左联接而不是销售表的计数?

Sql server 是否消除来自左联接而不是销售表的计数?,sql-server,tsql,Sql Server,Tsql,以下查询返回每月的销售额,无论该月是否为0。如果我将@sales按月分组,那么它将在2月份返回一次销售,4月份返回两次销售。这是正确的 因为这将在以后用作运行总数,所以我需要所有月份的计数,即使是0。所以我用表做了一个左连接1@months`因此,无论计数多少,每个月都会返回 declare @sales table ( salesdate date ) insert into @sales select '2/20/2021' union select '4/15/2021' unio

以下查询返回每月的销售额,无论该月是否为0。如果我将
@sales
按月分组,那么它将在2月份返回一次销售,4月份返回两次销售。这是正确的

因为这将在以后用作运行总数,所以我需要所有月份的计数,即使是0。所以我用表做了一个左连接1@months`因此,无论计数多少,每个月都会返回

declare @sales table
(
    salesdate date
)
insert into @sales
select '2/20/2021' union
select '4/15/2021' union
select '4/20/2021'

/* This result is correct: will return two rows: one sale in February and 2 sales in April */
select month(salesdate) as monthnumber, count(*) 'salesTotal' from 
@sales
group by month(salesdate)
order by month(salesdate)




declare @months table 
(
    monthnumber int,
    monthname varchar(10)
)
insert into @months
select 1, 'January' union
select 2, 'February' union
select 3, 'March' union
select 4, 'April' union
select 5, 'May'


select m.monthname, m.monthnumber, count(*)
from @months m left join @sales s on
m.monthnumber = month(salesdate)
group by m.monthname, m.monthnumber
最后一个查询返回以下结果:

monthname        monthnumber        TotalSales
January          1                  1
February         2                  1    //This is correct
March            3                  1
April            4                  2    //This is correct
May              5                  1
此结果的问题是,即使实际销售计数为0,左联接也将始终返回正计数(*)


如果当月没有任何销售,如何排除行计数?

您需要一个聚合,在左连接不匹配的情况下,将区分@sales中的非NULL值和NULL值,而不是执行
count(*)
。试着这样做:

select m.monthname, m.monthnumber, sum(case when s.salesdate is not null then 1 else 0 end)
from @months m 
left join @sales s 
    on m.monthnumber = month(salesdate)
group by m.monthname, m.monthnumber

CASE
语句结合使用的
SUM()
将只统计匹配的销售额,而不是总是统计由于左连接丢失而导致的单个空行。

这是一个比@pwang更简单的解决方案(在某些情况下非常有用),只需在列上使用
COUNT

COUNT
只计算非空值,因此我们可以从
sales
表中指定一列,如果没有联接结果,该列将为空:

选择
m、 蒙特纳姆,
m、 蒙纳姆,
计数(销售日期)
从@m月开始
左键连接@sales
月日编号=月(销售日期)
由m.monthname、m.monthnumber组成的分组

该列必须是
非空
列,否则结果可能不正确。

非常感谢。效果很好。