如何在24小时内运行COUNT()

时间:2015-03-15 18:55:13

标签: sql postgresql aggregate-functions

首先,我浏览了所有类似的问题(like this one),但似乎没有一个完全相同。

我试图在滚动的24小时内找到最多的动作。表中的示例数据如下所示:

id  |  datetime      
--------------------------
1   | 2015-03-01 12:01:00
2   | 2015-03-01 12:01:30
3   | 2015-03-01 12:02:42
4   | 2015-03-01 12:05:18
5   | 2015-03-01 12:07:22
6   | 2015-03-02 13:26:59

依旧......

我想在一定时间间隔内找到任何 24小时窗口内销售的最大商品数量。我知道这个SQL目前还没有工作,但是达到了我想要做的事情:

SELECT
    date_trunc('hour',i.dateSold AT TIME ZONE 'America/Chicago') AS endHour,
    SUM(CASE WHEN i.dateSold >= i.dateSold - INTERVAL '24 HOURS' AND i.dateSold < i.dateSold AT TIME ZONE 'America/Chicago' THEN 1 ELSE 0 END) as itemsSold
FROM items_sold i
WHERE
    i.dateSold >= '2015-03-13 00:00:00 America/Chicago'
    AND i.dateSold < '2015-03-16 00:00:00 America/Chicago'
GROUP BY
    date_trunc('hour',i.dateSold AT TIME ZONE 'America/Chicago')

我的想法是,我可能需要建立一个包含开始和结束日期的CTE,但是我无法提出可行的解决方案。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

我提前道歉,因为这有点远。这是MySQL的语法(虽然我相信它是相当标准的SQL)并且我没有对它进行过广泛的测试,所以我觉得它很有用,我不知道它的性能,但它应该给你指向正确的方向。

SELECT 
   sales1.date AS startdate, 
   max(sales2.date) AS enddate,
   count(sales2.id) AS count
FROM sales AS sales1 
   JOIN sales AS sales2 
       ON (sales2.date > sales1.date 
           AND sales2.date <= sales1.date + INTERVAL 1 DAY) 
GROUP BY startdate 
ORDER BY startdate

答案 1 :(得分:1)

Postgres中没有名为datetime的数据类型。你可能会把它与MySQL混淆(就像其他一些答案一样)。

您似乎混合了timestamptimestamptz数据类型,如果您不知道自己在做什么,这种数据类型就不会很好。首先阅读:

这是一个的原因(以及其他原因),为什么你应该用你的问题发布你的实际和确切的表格定义。

your comment(问题中应该是)判断,您希望24小时开始并在午夜结束。那不是一个24小时的滚动时间&#34;这只是过去的日子。只有时区仍不清楚。

假设 timestamp [without time zone] 喜欢您的测试数据建议并且忽略未申报的时区问题。致(我引用):

  

查找在一定时间间隔内任何24小时窗口内销售的最大商品数量。

SELECT date_sold::date AS day, count(*) AS item_count
FROM   items_sold
WHERE  date_sold >= '2015-03-13 0:0'  -- timestamp format ...
AND    date_sold <  '2015-03-16 0:0'  -- ... not timestamptz
GROUP  BY 1
ORDER  BY 2 DESC
LIMIT  1;

根据您的实际表格定义以及您对时区的计划,您需要进行调整。

答案 2 :(得分:0)

如果我理解正确,您可以记录每件商品的销售情况。然后,在1天后添加记录,说记录不再重要。然后,您可以在24小时内完成累计项目总和,并通过排序和使用limit选择最大值:

select dateSold, sum(item) over (order by i.dateSold) as numItems
from (select i.dateSold, 1 as item
      from items_sold
      union all
      select i.dateSold + interval '1 day', -1 as item
      from items_sold
     ) i
order by numItems desc
limit 1;