无法使用完全外连接获取空值

Can not get null values with full outer join

我正在使用 SQL 服务器。 我有一个 table Dim_date,所有日期都是 2020 年 5 月

Datekey
---------
20200501 
20200502
20200503
20200504
20200505
20200506
20200507
....

我有一个 table Fact_Controls 有特定 centre 完成的控制数量每一天。

Date_Ctl | Id_Centre | No_Controls
---------------------------
20200505| 01415     |1
20200505| 01415     |1
20200505| 01415     |1
20200506| 01415     |1
20200506| 01415     |1

我想要一个查询,显示一个中心完成的控制数量,即使它是 0 或 null,例如:

Datekey | Id_Centre | No_Controls
---------------------------
20200501| 01415     |0
20200502| 01415     |0
20200503| 01415     |0
20200504| 01415     |0
20200505| 01415     |3
20200506| 01415     |2
20200507| 01415     |0
....

我正在这样做,但没有得到我期望的结果:

select 
     dd.DateKey,
     sum(No_Controls) as total_controls
from 
      [Fact_Controls] fc
full outer join 
     [dm].[Dim_Date] dd on  fc.Date_Ctl = dd.DateKey
where 
     fc.[Id_Centre]='01415' 
    and fc.Date_Ctl between 20200501 and 20200520
    and dd.DateKey is null
group by dd.DateKey

请使用外部应用

SELECT * FROM [Dim_Date] D 
OUTER APPLY 
   ( 
   SELECT * FROM [Fact_Controls] F 
   WHERE F.Date_Ctl = D.DateKey 
   ) A 
GO

外连接行在没有匹配行的列中有空值。所以这个

where fc.[Id_Centre]='01415' and fc.Date_Ctl between 20200501 and 20200520

将删除所有外部连接的 fc 行。

这个

where dd.DateKey is null

另一方面,将删除所有未外部连接的 dd 行。

另外,为什么要全外连接?日期 table 不应该包含所有日期吗?看来您只需要一个左外连接:

select
  dd.datekey,
  sum(fc.no_controls) as total_controls
from dm.dim_date dd 
left join fact_controls fc on  fc.date_ctl = dd.datekey and fc.id_centre = '01415' 
where dd.datekey between '20200501' and '20200520'
group by dd.datekey
order by dd.datekey;

或(加入前聚合):

select dd.datekey, fc.total_controls
from dm.dim_date dd 
left join
(
  select date_ctl, sum(no_controls) as total_controls
  from fact_controls
  where id_centre = '01415'
  group by date_ctl
) fc on  fc.date_ctl = dd.datekey
where dd.datekey between '20200501' and '20200520'
order by dd.datekey;

或(按日期行直接聚合):

select dd.datekey, fc.total_controls
from dm.dim_date dd 
outer apply
(
  select sum(no_controls) as total_controls
  from fact_controls
  where id_centre = '01415'
  and by date_ctl = dd.datekey
) fc
where dd.datekey between '20200501' and '20200520'
order by dd.datekey;

您可以使用合并将结果中的空值变为零。

如果 datekey + id_centre 在您的 table fact_controls 中是唯一的,您当然根本不需要聚合 (SUM)。