【问题标题】:SQL - linking using date to 'between 2 dates' logicSQL - 使用日期链接到“两个日期之间”的逻辑
【发布时间】:2018-02-02 12:39:19
【问题描述】:

SQL - 我有带有值和相应日期的表 Values 和带有期间标签和这些期间的开始日期(不规则日期)的表 Periods

我正在尝试链接两个表,以便为每个具有相应日期的值分配一个与每个时期相关的标签(基于日期检查)。有一个例子:

Periods
--------
Desc  Dates
M1    03/01/2000
M2    05/02/2000
M3    10/03/2000
...
M12   01/12/2000


Values
-------
Value_Date   Value
05/01/2000   101
01/02/2000   201

07/02/2000   301
15/02/2000   401

我想得到这样的东西:

Results_1
----------
Value_Date   Value  Desc
05/01/2000   101    M1
01/02/2000   201    M1
07/02/2000   301    M2
15/02/2000   401    M2

 and then 


Results_2
----------
Desc   Value_Total
M1     302
M2     702

在 Athena/Presto SQL 中执行此操作的有效方法是什么?

【问题讨论】:

  • 我正在使用 Athena/Presto
  • 附带说明:您应该避免使用 SQL 单词的名称(descvalues)。

标签: sql presto amazon-athena


【解决方案1】:

您可以加入开始日期小于或等于起息日的所有期间,然后关闭除最晚的所有期间。这可能效率不高,但确实有效。

select ranked.desc, sum(value) as total
from
(
  select
    v.value_date,
    v.value,
    p.desc,
    row_number() over (partition by v.value_date, v.value order by p.dates desc) as rn
  from values v
  join periods p on p.dates <= v.value_date
) ranked
where rn = 1
group by ranked.desc
order by ranked.desc;

(如果value_datevalues 表中是唯一的,那么您可以从分区子句中删除, v.value。)

【讨论】:

    【解决方案2】:

    您可以使用LEAD 获取期间的结束日期。然后加入很简单。

    with complete_periods as
    (
      select 
        p.desc,
        p.dates as start_date,
        coalesce(
          lead(p.dates) over (order by start_date) - interval '1' day,
          date '2999-12-31' -- high date, so we don't have to deal with null
        ) as end_date
      from periods p
    )
    select p.desc, sum(v.value) as total
    from values v
    join complete_periods p on v.value_date between p.start_date and p.end_date
    group by p.desc
    order by p.desc;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 2019-11-21
      • 2018-07-25
      相关资源
      最近更新 更多