无法使用完全外连接获取空值
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
)。
我正在使用 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
)。