5

我想按时间间隔对表中的数据进行分组。该表保留了订单信息,包括用户 ID、商品名称、型号、数量、活动日期等。现在我想按时间间隔对这些数据进行分组。时间间隔可以是 5 分钟、10 分钟、15 分钟等。此外,查询应该只返回在 5 分钟间隔内多次下订单的用户(所有列数据)。是否可以在一个 SQL 查询中实现这一点?我使用甲骨文。

谢谢

编辑:

样本数据

**userid    item name    model      quantity   order date**
abc calculator   cdm83ss    1      02-FEB-2013 09:20:13     
abc alarm clock  actp001    1      02-FEB-2013 09:26:22
yyy iPhone       iP4    1      02-FEB-2013 09:28:14
abc alarm clock  actz321    2      02-FEB-2013 09:30:00
zzz backpack     bp344tk    1      04-FEB-2013 13:15:00
zzz backpack     bp234zz    2      04-FEB-2013 13:19:32
zzz camera       cm234  1      04-FEB-2013 13:20:22 
ttt tv       fs45yup    1      04-FEB-2013 13:28:19

我希望得到:

**userid    item name    model      quantity   order date**
abc         calculator   cdm83ss    1      02-FEB-2013 09:20:13     
abc         alarm clock  actp001    1      02-FEB-2013 09:26:22
abc         alarm clock  actz321    2      02-FEB-2013 09:30:00
zzz         backpack     bp344tk    1      04-FEB-2013 13:15:00
zzz         backpack     bp234zz    2      04-FEB-2013 13:19:32
zzz         camera       cm234  1      04-FEB-2013 13:20:22 
4

2 回答 2

7

是的。大概您也希望将结果视为日期时间值。这需要一些日期时间算法。基本上,获取自午夜以来的分钟数,除以分钟数,然后再次相乘(向下舍入)。然后加回午夜的时间:

select t.*
from (select t.*,
             count(*) over (partition by userid, interval) as CntInInterval
      from (select trunc(orderdate)+
                   (floor(((orderdate - trunc(orderdate))*24*60)/10)*10)/(24*60) as interval, t.*
            from t
           ) t
     ) t
where cntInInterval > 1

要按时间间隔分组,您可以使用:

      select interval, count(*)
      from (select trunc(orderdate)+floor(((orderdate - trunc(orderdate))*24*60)/10)*10 as interval, t.*
            from t
           ) t
      group by interval

在这些查询中,“10”代表任意分钟数。请注意,这些是从午夜开始计算的,因此像 17 这样的值总是从一天的前 17 分钟开始。

区间的定义是日期的算术表达式。

          trunc(orderdate)+floor(((orderdate - trunc(orderdate))*24*60)/10)*10 作为间隔,

第一部分trunc(orderdate)是 Oracle 语法,用于删除日期的时间部分。这会将日期移至一天开始时的午夜。

该表达式orderdate - trunc(orderdate)计算自午夜以来的天数——这是一天的小数部分。因此,0.25 将是 6:00 am 将其*24*60转换为分钟。因此,0.25 变为 0.25*60*24 = 360 - 自午夜以来的分钟数。

然后表达式floor(x/y)*y简单地将任何值“截断”为 y 的较低倍数。所以,floor(118/10)是 11,而 11*10 是 110。换句话说,这会将 a*y 和 (a+1)*y(直到不包括)之间的所有值映射到相同的值 a*y。

在 2013 年 1 月 1 日上午 6:08 考虑实践中的表达:

`trunc(orderdate)` moves the date to midnight on 2013-01-01.
`orderdate - trunc(orderdate)` creates a number like 0.25.
`((orderdate - trunc(orderdate))*24*60)` produces the value 368
`floor(((orderdate - trunc(orderdate))*24*60)/10)*10` produces 360
`floor(((orderdate - trunc(orderdate))*24*60)/10)*10*(1/24*60)` produces 0.25

再加上一分钟,时间又变成了早上 6:00。

于 2013-02-08T21:07:04.960 回答
3

如果您需要更简单的方法来获取时间间隔 - 我无法为您提供任何其他帮助,因为我不知道您的表格和数据:

-- Time interval - every 15 min from midnight --
SELECT To_Char(trunc(SYSDATE) + (LEVEL/1440*15), 'HH24:MI') interval_15_min 
  FROM dual
CONNECT BY LEVEL <= 10 -- this is orbitraty 
/
SQL>

INTERVAL_15_MIN
--------------
00:15
00:30
00:45
...
于 2013-02-08T21:45:19.597 回答