SQL 加入以填充缺失值

SQL join for filling missing values

我有一个table的历史数据(#Records);在存储过程结束时,我需要根据 table 日期 (dbo.MasterDates) 填充数据。对于下面的简化示例,我将简单地使用 City 作为唯一数据系列的标识符。

tempdb.dbo.#记录:

日期 城市 价值
2021-06-04 洛杉矶 10.5
2021-06-04 纽约 11.2
2021-06-05 洛杉矶 9.2
2021-06-06 纽约 8.1

dbo.Dates:

日期 年份 月份
2021-06-04 2021 6 4
2021-06-05 2021 6 5
2021-06-06 2021 6 6

如果数据被过滤,因此只有一个系列被检索 (即,只有纽约市的数据),填充将是一个简单的 select 来自 dbo.Dates#Records 上的 left outer join。但是,我需要填写每个城市的每一天的记录。

例如(已填记录 加粗)

日期 城市 价值
2021-06-04 洛杉矶 10.5
2021-06-04 纽约 11.2
2021-06-05 洛杉矶 9.2
2021-06-05 纽约市 0.0
2021-06-06 LA 0.0
2021-06-06 纽约 8.1

我的第一次尝试是创建一个版本的 dbo.Dates,其中包含每个独特城市的记录,然后用它来填充 #记录 table:

insert into #FilledDates (Date, City)
select
    dates.Date, City
from Dates d
cross apply
(
    select distinct City from #Records
) r

select
    d.Date, d.City, isnull(r.Value, 0)
from #FilledDates d
left outer join #Records r on r.Date = d.Date and r.City = d.City

这很好用;然而,考虑到实际用例要复杂得多,我很好奇是否有更好的方法来达到预期的结果。性能是我主要关心的问题...似乎我应该能够结合交叉应用和连接步骤,但是我对交叉应用还是有点陌生​​。

创建一个包含所有可能 city/date 组合的投影,然后加入:

WITH Projection AS (
    SELECT City, [Date]
    FROM Dates
    CROSS JOIN (SELECT DISTINCT City FROM Records) c
)
SELECT p.*, coalesce(r.[Value], 0.0) as [Value]
FROM Projection p
LEFT JOIN #Records r ON r.[Date] = p.[Date] AND r.City = p.City
ORDER BY [Date], City

在这里查看它的工作原理:

http://sqlfiddle.com/#!18/bebc4/4/0