如何在单个查询中获取一天的计数和最近三天的计数?

Posted

技术标签:

【中文标题】如何在单个查询中获取一天的计数和最近三天的计数?【英文标题】:How to get count of one day and count of last three days in single query? 【发布时间】:2016-03-17 16:44:26 【问题描述】:

这是一个类似的问题:How to get sum of one day and sum of last three days in single query?

假设我有一个这样的统计表:

date | stats
-------------
10/1 | 2
10/1 | 3
10/1 | 2
10/2 | 1
10/3 | 3
10/3 | 2
10/4 | 1
10/4 | 1

我想要的是三列:

    日期 count(distinct stats) of Date 日期前最后三天的计数(不同的统计数据)

所以我预期结果中的唯一一行应该是:

date | today | last three day
-----+-------+---------------
10/4 |   1   |      3

这个问题和我之前提到的类似问题的不同之处在于,我们不能通过使用 sum(count(distinct stats)) over (...) 来计算最近三天的不同统计数据,因为同一种统计数据在不同的日子出现会被计算多次。

我应该怎么做才能存档?

谢谢!

【问题讨论】:

@GordonLinoff 你好,这是我的新问题,你能帮帮我吗?谢谢:D 【参考方案1】:

我认为您需要另一个查询来解决它,例如使用同一个表的左外连接来存档它。

您的数据和其他一些数据。

date | stats
-------------
10/1 | 2
10/1 | 3
10/1 | 2
10/2 | 1
10/3 | 3
10/3 | 2
10/4 | 1
10/4 | 1
10/7 | 2
10/8 | 3
10/9 | 2
10/10 | 4
10/10 | 3
10/10 | 2
10/11 | 1
10/12 | 4

我通过这个查询来获取示例数据:

SELECT  unnest(array[   '2015/10/1','2015/10/1','2015/10/1','2015/10/2','2015/10/3','2015/10/3','2015/10/4','2015/10/4',
                    '2015/10/7', '2015/10/8', '2015/10/9', '2015/10/10', '2015/10/10', '2015/10/10', '2015/10/11', '2015/10/12'])::date as date, 
            unnest(array[   2, 3, 2, 1, 3, 2, 1, 1,
                    2, 3, 2, 4, 3, 2, 1, 4]) as stats
    ) AS F

现在我进行查询以获取您需要的数据:

SELECT  f.date, count(distinct f.stats), count(distinct x.stats)
    FROM    (
        SELECT  unnest(array[   '2015/10/1','2015/10/1','2015/10/1','2015/10/2','2015/10/3','2015/10/3','2015/10/4','2015/10/4',
                    '2015/10/7', '2015/10/8', '2015/10/9', '2015/10/10', '2015/10/10', '2015/10/10', '2015/10/11', '2015/10/12'])::date as date, 
            unnest(array[   2, 3, 2, 1, 3, 2, 1, 1,
                    2, 3, 2, 4, 3, 2, 1, 4]) as stats
    ) AS F
    LEFT OUTER JOIN (SELECT  unnest(array[  '2015/10/1','2015/10/1','2015/10/1','2015/10/2','2015/10/3','2015/10/3','2015/10/4','2015/10/4',
                    '2015/10/7', '2015/10/8', '2015/10/9', '2015/10/10', '2015/10/10', '2015/10/10', '2015/10/11', '2015/10/12'])::date as date, 
            unnest(array[   2, 3, 2, 1, 3, 2, 1, 1,
                    2, 3, 2, 4, 3, 2, 1, 4]) as stats) AS x
    ON x.date BETWEEN f.date - INTERVAL '3 DAYS' AND  f.date 
    GROUP BY f.date

结果:

date;today;last three day
    "2015-10-01";2;2
    "2015-10-02";1;3
    "2015-10-03";2;3
    "2015-10-04";1;3
    "2015-10-07";1;2
    "2015-10-08";1;2
    "2015-10-09";1;2
    "2015-10-10";3;3
    "2015-10-11";1;4
    "2015-10-12";1;4

我希望这个解决方案会有所帮助。

【讨论】:

是的,这可以完成这项工作。感谢您的帮助:D 太好了,很高兴为您提供帮助。【参考方案2】:

我倾向于使用相关子查询来做到这一点:

select t.date, count(distinct stats),
       (select count(distinct t2.stats)
        from t t2
        where t2.date >= t.date - interval '3 day' and
              t2.date < t.date
       )
from t
group by date;

【讨论】:

以上是关于如何在单个查询中获取一天的计数和最近三天的计数?的主要内容,如果未能解决你的问题,请参考以下文章

Redshift SQL:如何获取今天的计数和前 3 天的计数总和

oracle求查询连续三天的数据

基数计数——HyperLogLog

基数计数及HyperLogLog算法

Pandas - 最近 x 天的值的计数频率

请问下用Oracle数据库,怎么实现查询表里最近三天的所有信息。求大神解。