【问题标题】:PostgreSQL combining a count, a last 7 days count and a last 30 days count Grouped by daysPostgreSQL 结合计数、最近 7 天计数和最近 30 天计数按天分组
【发布时间】:2020-08-19 09:42:46
【问题描述】:

我有一张小桌子 (TABLEA),它有两列 IDADATETIMEA

表格

IDA  DATETIMEA
1    2020-03-16 13:15:00
2    2020-03-17 15:25:00
3    2020-03-18 17:10:00
5    2020-03-19 11:44:00
5    2020-03-20 12:55:00
5    2020-03-21 19:35:00
7    2020-03-22 10:13:00
8    2020-03-22 15:25:00
8    2020-03-28 12:12:00
9    2020-03-29 17:55:00
10   2020-03-30 11:54:00
12   2020-03-30 15:35:00
12   2020-03-31 13:19:00

我正在尝试获取每天IDA 的总数、过去 7 天的总数和过去 30 天的总数。

预期输出

DATE       DAY L7 L30
2020-03-16 1   1  1
2020-03-17 1   2  2
2020-03-18 1   3  3
2020-03-19 1   4  4
2020-03-20 1   5  5
2020-03-21 1   6  6
2020-03-22 2   8  8  
2020-03-28 1   3  9
2020-03-29 1   4  10
2020-03-30 2   6  12
2020-03-31 1   7  13

我尝试将与日期相关的输出放在子查询中,但它们返回 0。

SELECT t.DATETIMEA::date date,
COUNT(t.*) "day",
(SELECT COUNT(w.*) FROM TABLEA w WHERE w.DATETIMEA::date BETWEEN w.DATETIMEA::date AND w.DATETIMEA::date - 7) week,
(SELECT COUNT(m.*) FROM TABLEA m WHERE m.DATETIMEA::date BETWEEN m.DATETIMEA::date AND m.DATETIMEA::date - 30) "month"
FROM TABLEA t
GROUP BY t.DATETIMEA::date
ORDER BY t.DATETIMEA::date

【问题讨论】:

  • 12 是真的重复还是错字?
  • @GordonLinoff 是的,表明 IDA 不是唯一的

标签: sql postgresql datetime count date-arithmetic


【解决方案1】:

如果您的数据可能在几天内出现间隔,那么您需要一个 range 框架规范,而不是一个 rows 框架。很高兴 Postgres 支持这个规范,所以你可以这样做:

select
    datetimea::date date,
    count(*) "day",
    sum(count(*)) over(
        order by datetimea::date
        range between '7 day' preceding and current row
    ) l7,
        sum(count(*)) over(
        order by datetimea::date
        range between '30 day' preceding and current row
    ) l30
from mytable
group by datetimea::date
order by datetimea::date 

Demo on DB Fiddle

日期 |天 | l7 | l30 :--------- | --: | -: | --: 2020-03-16 | 1 | 1 | 1 2020-03-17 | 1 | 2 | 2 2020-03-18 | 1 | 3 | 3 2020-03-19 | 1 | 4 | 4 2020-03-20 | 1 | 5 | 5 2020-03-21 | 1 | 6 | 6 2020-03-22 | 2 | 8 | 8 2020-03-28 | 1 | 4 | 9 2020-03-29 | 1 | 4 | 10 2020-03-30 | 2 | 4 | 12 2020-03-31 | 1 | 5 | 13

【讨论】:

  • 白天工作,但 l7 和 l30 的数字很大,例如 2020-03-16 day: 1 L7 and L30 = 0.76e2
  • @Matt:这确实适用于您在小提琴中的示例数据(我认为l7 中的差异是由于您的拼写错误造成的)。你怎么知道结果是错误的?
  • 我的数据只是样本数据的更大版本,我可以说错,因为总数不应该是 0.76e2
  • @Matt: 也许你想要count(distinct ida) 而不是count(*)(替换所有三个出现的count(*))?在没有看到证明问题的示例数据的情况下,我只能猜测。
  • 实际上是 GMB,我刚刚在 dbfiddle 上重新创建了我的,它可以工作,而在大象sql.com 上它得到的值不正确
【解决方案2】:

我认为窗口函数可以满足您的需求:

select t.datetimea::date, count(*) as on_day,
       sum(count(*)) over (order by t.datetimea::date rows between 6 preceding and current row) as sum_7,
       sum(count(*)) over (order by t.datetimea::date rows between 29 preceding and current row) as sum_30
from tablea t
group by t.datetimea::date;

“过去 7 天”是指今天和之前的 6 天。如果您指的是今天前 7 天,则可以轻松调整窗框。

【讨论】:

  • 白天工作,但 l7 和 l30 的数字很大,例如 2020-03-16 day: 1 L7 and L30 = 0.76e2
猜你喜欢
  • 2020-04-08
  • 2017-09-25
  • 2017-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-27
相关资源
最近更新 更多