【问题标题】:How to repeat dates for multiples values and fill missing dates in SQL如何在 SQL 中重复多个值的日期并填充缺失的日期
【发布时间】:2020-04-24 03:03:50
【问题描述】:

我有一个包含日期、ID 和值的表格,如下所示

我想为所有 ID 重复日期范围(开始日期、结束日期),如果任何日期的值缺失,请输入 0。

如何在 SQL 中实现这一点? 提前致谢

【问题讨论】:

  • 你能举个例子解释一下你的逻辑吗?
  • 我正在尝试为所有 ID 重复日期。我有第一张图片所示的数据。我想为所有 id 重复一个日期,例如所有 id 的 01-02-2020,如果 id 在该日期没有值则设置为 0。

标签: sql date recursion missing-data


【解决方案1】:

只需使用cross join 生成行并使用left join 引入现有值:

select i.id, t.date, coalesce(t.value, 0) as value
from (select distinct id from t) i cross join
     (select distinct date from t) left join
     t
     on t.id = i.id and t.date = i.date;

您可以使用insert intoselect into 将此数据放入另一个表中。

【讨论】:

  • 但是,我认为我们仍然需要有日期表。如果没有日期表,可能会丢失日期,其中没有一个 id 有值。使用日期表,我认为您的解决方案会很好。
  • @VenkataramanR 。 . .在问题中,所有日期都表示出来。
  • 知道了。我认为它需要整个月。谢谢。
  • @VenkataramanR 。 . .你的答案有效。我只是回答,因为它似乎不必要地复杂。即使 OP 需要生成日期并且没有数字或日历表,仍然可以在单个查询中完成。
【解决方案2】:

我在 SQL Server 中尝试过以下示例。

  1. 首先,您需要一个包含日期列表的日期表。
  2. 然后,你需要有日期、id 值的组合
  3. 现在,如果日期存在,则需要填写 val,否则将为 0。
DECLARE @FromDate DATETIME, @ToDate DATETIME;
SET @FromDate = '2020-02-01';
SET @ToDate = '2020-02-28';
DECLARE @DateTable TABLE(theDate DATE) 
DECLARE @datasource TABLE(id int, dateVal DATE, Val INT)

-- all days in that period
INSERT INTO @DateTable 
SELECT TOP (DATEDIFF(DAY, @FromDate, @ToDate)+1) 
  TheDate = CAST(DATEADD(DAY, number, @FromDate) AS DATE)
  FROM [master].dbo.spt_values 
  WHERE [type] = N'P' ORDER BY number;

--
INSERT INTO @datasource
VALUES
(59895,'2020-02-01',5),(59895,'2020-02-03',7),
(59888,'2020-02-01',2),(59888,'2020-02-02',10)

;WITH CTE_idDates AS
(
SELECT theDate,id FROM @DateTable
CROSS JOIN 
@datasource
)
SELECT theDate, id,
COALESCE((SELECT Val from @dataSource WHERE dateval=c.thedate and id=c.id),0)
FROM CTE_idDates AS c

结果集

+------------+-------+------------------+
|  theDate   |  id   | (No column name) |
+------------+-------+------------------+
| 2020-02-01 | 59895 |                5 |
| 2020-02-02 | 59895 |                0 |
| 2020-02-03 | 59895 |                7 |
| 2020-02-04 | 59895 |                0 |
| 2020-02-05 | 59895 |                0 |
| 2020-02-06 | 59895 |                0 |
.
.
.
| 2020-02-28 | 59895 |                0 |
| 2020-02-01 | 59888 |                2 |
| 2020-02-02 | 59888 |               10 |
.
.
.
| 2020-02-26 | 59888 |                0 |
| 2020-02-27 | 59888 |                0 |
| 2020-02-28 | 59888 |                0 |
+------------+-------+------------------+

【讨论】:

  • 效果很好。太感谢了。我需要做什么才能将最终结果添加到临时表中以将其用于另一个查询?
  • 您可以加载到临时表中,并根据需要使用另一个查询。或者你可以去另一个 CTE 并在另一个查询中使用 CTE
  • 我正在尝试在临时表中加载最后一个 CTE,但我对 c.thedate 和 c.id 的工作方式感到困惑。你能分享查询来为最后一个结果创建一个临时表吗?这对我很有帮助。
  • 无论我用过什么,我都给出了答案。尝试从答案中得出你的案例
  • @kulvir 。 . .这比必要的要复杂得多。这不需要临时表。
猜你喜欢
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-08
相关资源
最近更新 更多