【问题标题】:SQL - BigQuery - How do I fill in dates from a calendar table?SQL - BigQuery - 如何从日历表中填写日期?
【发布时间】:2020-12-16 17:26:06
【问题描述】:

我的目标是将销售计划表连接到日历表,这样就会有一个连接表,其中包含完整的尾随 52 周,然后将销售数据连接到它。这个想法是,我可以在事后 COALESCE 有空值。但是,我的问题是我只能从我的销售数据表中得到不带空值的结果。

目前我咨询过的问题有:

Join to Calendar Table - 5 Business Days

Joining missing dates from calendar table哪个指向

MySQL how to fill missing dates in range?

我的日历表是​​今天之前的 364 天(今天是第 0 天)。销售数据有一个程序字段、一个商店字段,然后是程序的开始日期和结束日期。

这是我编写的代码:

SELECT 
    CAL.DATE,
    CAL.DAY,
    SALES.ITEM,
    SALES.PROGRAM,
    SALES.SALE_DT,
    SALES.EFF_BGN_DT,
    SALES.EFF_END_DT
  FROM 
    CALENDAR_TABLE AS CAL
  LEFT JOIN 
    SALES_TABLE AS SALES
  ON CAL.DATE = SALES.SALE_DT
  WHERE 1=1
    and SALES.ITEM = 1 or SALES.ITEM is null
  ORDER BY DATE ASC

我的预期是 365 条记录,其中日期为空值,日期为记录。我的查询导致一些日期为空值,但其他日期只是程序存在的日期。

   DATE   |  ITEM  | PROGRAM | SALE_DT  | PRGM_BGN  | PRGM_END  |
----------|--------|---------|----------|-----------|-----------|
8/27/2020 |        |         |          |           |           |
8/26/2020 |        |         |          |           |           |
8/25/2020 |        |         |          |           |           |
8/24/2020 |        |         |          |           |           |
6/7/2020  |    1   |    5    | 6/7/2020 | 2/13/2016 |  6/7/2020 |
6/6/2020  |    1   |    5    | 6/6/2020 | 2/13/2016 |  6/7/2020 |
6/5/2020  |    1   |    5    | 6/5/2020 | 2/13/2016 |  6/7/2020 |
6/4/2020  |    1   |    5    | 6/4/2020 | 2/13/2016 |  6/7/2020 |

Date = Calendar day.
Item = Item number being sold.
Program = Unique numeric ID of program.
Sale_Dt = Field populated if at least one item was sold under this program.
Prgm_bgn = First day when item was eligible to be sold under this program.
Prgm_end = Last day when item was eligible to be sold under this program.

我所期望的是 6 月 7 日至 8 月 24 日之间的记录,其中仅填充了每天的 DATE 列和最近四条记录中发生的空值。

我试图了解为什么日历表和我所写的内容没有提供中间日期。

编辑:我已经删除了反馈请求以缩短问题以及我认为没有附加价值的示例。但请继续提供您认为有必要的反馈。

【问题讨论】:

  • 谢谢!我现在会看一下,这样我就可以尝试用它来更新我的问题。
  • 您研究的 1 个具体的非重复问题是什么? “任何反馈”不是有效的 SO 问题。 How to Ask help center 您也可以通过 site:meta.SO 或 site:meta.SE 谷歌重新询问。 (或询问,但研究,包括那里的主题。)请use text, not images/links, for text--including tables & ERDs。仅将图像用于无法表达为文本或增强文本的内容。在图片中包含图例/键和说明。
  • 请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。给出尽可能少的代码,即您显示的代码可以通过您显示的代码扩展为不正常的代码。 (调试基础。)对于包含 DBMS 和 DDL(包括约束和索引)和输入为格式化为表的代码的 SQL。 How to Ask 暂停总体目标的工作,将代码砍到第一个表达式,没有给出你期望的内容,说出你的期望和原因。
  • 您的where 子句是否正确?注意和/或的操作顺序。考虑重写为WHERE IFNULL(SALES.ITEM,1) = 1

标签: sql date join google-bigquery


【解决方案1】:

我很乐意删除整个问题或让其他人给出更好的答案,但是在盯着这个线程 (MySQL how to fill missing dates in range?) 中一些答案的逻辑足够长之后,我想出了这个:

SELECT
  CAL.DATE,
  t.* EXCEPT (DATE)
FROM  
  CALENDER_TABLE AS CAL
LEFT JOIN
      (SELECT 
        CAL.DATE,
        CAL.DAY,
        SALES.ITEM,
        SALES.PROGRAM,
        SALES.SALE_DT,
        SALES.EFF_BGN_DT,
        SALES.EFF_END_DT
      FROM 
        CALENDAR_TABLE AS CAL
      LEFT JOIN 
        SALES_TABLE AS SALES
      ON CAL.DATE = SALES.SALE_DT
      WHERE 1=1
        and SALES.ITEM = 1 or SALES.ITEM is null
      ORDER BY DATE ASC) **t**
ON CAL.DATE = t.DATE  

据我所知,这似乎是我所需要的。它允许子查询将日期连接到所有这些记录,然后仅在日期上再次加入日历表以允许创建这些空值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    相关资源
    最近更新 更多