这个问题与这篇SO帖子有关。
不使用递归CTE,如何使用DimDates表添加缺失数据(通过日期确定为缺失)?
我有以下两个表:
以下是我希望获得的结果。我没有使用递归CTE,因为我错误地认为使用我们的仓库DimDate表会更容易:
不使用递归CTE,如何使用DimDates表添加缺失数据(通过日期确定为缺失)?
我有以下两个表:
create table the_table
(
[Date] datetime,
Category2 varchar(10),
Amount INT
)
insert into the_table
values
( '01 jan 2012', 'xx', 10),
( '03 jan 2012', 'yy', 50)
create table DimDate
(
[Date] datetime
)
insert into DimDate
values
( '01 jan 2012'),
( '02 jan 2012'),
( '03 jan 2012'),
( '04 jan 2012')
以下是我希望获得的结果。我没有使用递归CTE,因为我错误地认为使用我们的仓库DimDate表会更容易:
好的 - 如果我错了,请指出以下可能的解决方案的漏洞:
select
coalesce(x.[Date], y.[Date]) AS Date ,
coalesce(x.Category2, y.Category2) AS Category2 ,
isnull(Amount,0) as Amount
from the_table x
full outer join
(
select
d.Date
, t.Category2
from
the_table t
cross join DimDate d
) y
on
x.Category2 = y.Category2
and
x.Date = y.Date
我最终得到了这个结果。这是标记答案和Aaron帖子中的cte的组合:
;WITH
Dates_cte ([Date]) AS
(
SELECT [Date] = DayMarker
FROM WHData.dbo.vw_DimDate x
WHERE
x.DayMarker >= (SELECT MIN([Date]) FROM #Data1 WHERE Period = 'Daily') AND
x.DayMarker <= GETDATE()
)
,Categories ([Operator], [Market], [Product], [Measure]) AS
(
SELECT DISTINCT
[Operator]
, [Market]
, [Product]
, [Measure]
FROM #Data1
WHERE [Period] = 'Daily'
)
INSERT INTO #Data1
SELECT
c.[Operator]
, c.[Market]
, c.[Product]
, [Period] = CONVERT(VARCHAR(100), 'Daily')
, d.[Date]
, c.[Measure]
, 0
FROM Dates_cte d CROSS JOIN Categories c
WHERE NOT EXISTS
(
SELECT *
FROM #Data1 AS T
WHERE
t.[Period] = 'Daily' AND
t.[Operator] = c.[Operator] AND
t.[Market] = c.[Market] AND
t.[Product] = c.[Product] AND
t.[Measure] = c.[Measure] AND
t.[Date] = d.[Date]
)
CROSS JOIN
做同样的事情吗?- 我添加它的原因是为了获得笛卡尔积。 - whytheqSELECT dates.date, categories.category, ISNULL(data.val, 0) FROM dates CROSS JOIN categories LEFT JOIN data ON data.date = dates.date AND data.category = categories.category
[并不是所有情况都需要使用FULL OUTER JOIN.] - MatBailiet CROSS JOIN d
将产生一个巨大的表格,远不止是“所有日期和类别的组合”。你需要换个思路来得到一个好的查询:先创建一个包含所有你应该有的组合的模板,然后将你的数据左连接到它上面。 - MatBailieCROSS JOIN
? - whytheq