这个小例子基于我无数次遇到过的问题,但是我找不到最佳答案。
我想创建一份关于每个类型每月记录的事件的报告。写下面的查询。
SELECT
d.MonthPeriod
,i.[Type]
,COUNT(*) AS [Count of Calls]
FROM
[dbo].[FactIncident] as i
LEFT JOIN
[dbo].[DimDate] as d on i.DateLoggedKey = d.DateKey
GROUP BY
d.[MonthPeriod],
i.[Type]
这导致以下结果:
虽然这是正确的,但我想在早些时候看到0个已记录的电话。 DimDate包含以下内容。
显示所有月份每个类型的每月通话次数的最佳和/或最有效方式是什么。即使计数为0?
使用Cross Apply的想法,但结果查询很快就会变得很大。只考虑一个数据集,要求过去3年每个客户,每个类别,每个月的呼叫数量。
有什么想法吗?
答案 0 :(得分:1)
从日历表开始执行left join
,以便保留所有月份:
SELECT d.MonthPeriod, i.[Type], COUNT(i.type) AS [Count of Calls]
FROM [dbo].[DimDate] d LEFT JOIN
[dbo].[FactIncident] i
ON i.DateLoggedKey = d.DateKey
GROUP BY d.[MonthPeriod], i.[Type];
当然,这会将type
作为NULL
返回没有数据的月份。
如果您想要所有类型,请在类型上使用CROSS JOIN
。此示例从事实表中获取数据,但您可能有另一个包含每种类型的引用表:
SELECT d.MonthPeriod, t.[Type], COUNT(i.type) AS [Count of Calls]
FROM [dbo].[DimDate] d CROSS JOIN
(select distinct type from factincident) t LEFT JOIN
[dbo].[FactIncident] i
ON i.DateLoggedKey = d.DateKey and i.type = t.type
GROUP BY d.[MonthPeriod], t.[Type];