以不同的时间跨度分组

Posted

技术标签:

【中文标题】以不同的时间跨度分组【英文标题】:Grouping with different timespans 【发布时间】:2020-06-05 12:33:52 【问题描述】:

目前我正在努力实现一些有点重叠的聚合。

我表的当前结构是:

|ymd     |id|costs|
|--------|--|-----|
|20200101|a |10   |
|20200102|a |12   |
|20200101|b |13   |
|20200101|c |15   |
|20200102|c |1    |

但是,我想以每个项目具有不同时间跨度的方式对其进行分组。考虑到我在 20200103 上运行这个查询,我想要达到的结果是:

| timespan   | id | costs |
|------------|----|-------|
| last 2 days| a  |  22   |
| last 1 day | a  |  12   |
| last 2 days| b  |  13   |
| last 1 day | b  |  0    |
| last 2 days| c  |  16   |
| last 1 day | c  |  1    |

我已经尝试了很多事情,但到目前为止我无法实现我所需要的。这是我尝试过的查询,没有正确的结果:

SELECT 
    CASE 
        WHEN ymd BETWEEN date_add(current_date(),-2) AND to_date(current_date()) THEN '2 days' 
        WHEN ymd BETWEEN date_add(current_date(),-1) AND to_date(current_date()) THEN '1 day'
    END AS timespan,
    id,
    sum(costs) AS costs
FROM `table`
GROUP BY
    CASE 
        WHEN ymd BETWEEN date_add(current_date(),-2) AND to_date(current_date()) THEN '2 days' 
        WHEN ymd BETWEEN date_add(current_date(),-1) AND to_date(current_date()) THEN '1 day'
    END,
    id

【问题讨论】:

日期格式错误。 ymd between date... 仅当 ymd 在 yyyy-MM-dd 中时才能正常工作 我只是简化了我发布的示例。我实际上是在使用自定义 UDF 来转换日期并在 ymd 格式之上执行 date_diff 【参考方案1】:

您可以构建一个存储时间戳的派生表,将其与不同用户列表交叉连接以生成所有可能的组合,然后将表与left join 结合起来:

select d.timespan, i.id, coalesce(sum(t.costs), 0) costs
from (select distinct id from mytable) i
cross join (
    select 1 n, 'last 1 day' timespan
    union all select 2, 'last 2 day'
) d 
left join mytable t
    on t.ymd between date_add(current_date(), - d.n) and current_date()
group by d.n, d.timespan, i.id

【讨论】:

以上是关于以不同的时间跨度分组的主要内容,如果未能解决你的问题,请参考以下文章

mysql一条sql统计某个字段不同值的个数

如果列表中的索引,熊猫按功能分组以执行不同的方法

如何让谷歌跟踪直观地指示有错误的跨度

XSLT 1.0 将同一级别的多个相同节点以不同的值分组

Python with Selenium:点击拦截并找到不同的跨度类

以编程方式为 NativeScript Vue 中的标签设置“跨度”颜色在 FormattedString 中不起作用