按日期插入查询中的缺失值

Interpolate missing values in a query by date

给定以下查询

SELECT
    DATEADD(DAY, DATEDIFF(DAY, 0, [Created]), 0) [Date], 
    [Type], COUNT(*) as [Total]
FROM 
    Submissions 
WHERE 
    [Offer] = 'template1'
GROUP BY 
    DATEADD(DAY, DATEDIFF(DAY, 0, [Created]), 0), 
    [Type]
ORDER BY 1;

我得到以下输出:

Date                    Type                 Total
----------------------- -------------------- -----------
2021-04-30 00:00:00.000 Online               1
2021-05-01 00:00:00.000 Mail                 1
2021-05-01 00:00:00.000 Online               2
2021-05-10 00:00:00.000 Mail                 1

我的目标是确保对于每个日期,都汇总了两种类型。如果给定类型的行不存在,我想显示 0 而不是完全丢失该行。我该如何修改查询,例如,2021-04-30 存在 2 行,如图所示,一行的类型为 Online,另一行的类型为 Mail,总共为 0?

我使用下面的方法让它工作,但这似乎是一种非常蛮力的方法。

SELECT [Date], [Type], [Total] FROM
(
    SELECT
        DATEADD(DAY, DATEDIFF(DAY, 0, [Created]), 0) [Date],
        [Type]
    FROM 
        Submissions
    WHERE [Offer] = 'template1'
 ) t1
PIVOT (
    COUNT([Type])
    FOR [Type] in ([Mail],[Online])
) p
UNPIVOT 
(
    [Total] FOR [Type] in ([Mail],[Online])
) p2

这就是我正在寻找的结果:

Date                    Type                Total
----------------------- ------------------- -----------
2021-04-30 00:00:00.000 Mail                0
2021-04-30 00:00:00.000 Online              1
2021-05-01 00:00:00.000 Mail                1
2021-05-01 00:00:00.000 Online              2
2021-05-10 00:00:00.000 Mail                1
2021-05-10 00:00:00.000 Online              0

如果提交 table 没有特定日期的行,即使您的蛮力方法也不起作用。

标准方法是使用维度 tables 创建一个包含所有所需行的模板,然后将事实 table 加入其中。

SELECT
  calendar.date,
  type.label,
  COUNT(fact.id)
FROM
  calendar
CROSS JOIN
  type
LEFT JOIN
  submissions AS fact
    ON  fact.created >= calendar.date
    AND fact.created <  calendar.date + 1
    AND fact.type     = type.label
    AND fact.offer    = 'template1'
WHERE
    calendar.date BETWEEN ? AND ?
    AND type.label IN ('Mail', 'Online')
GROUP BY
  calendar.date,
  type.label

请原谅打字错误,我在phone