SQLite:在特定时间间隔内对数据进行分组

SQLite: Group data within certain time interval

我有一个 table 存储订单数据:

订单Table:

id | order_time          | quantity | ...
1  | 1592821854318       | 2
2  | 1592901538199       | 4
3  | 1592966454547       | 1
4  | 1593081282406       | 9
5  | 1593141826330       | 6

order_time table 是 UNIX 时间戳。

使用下面的查询,我能够获得按天分组的可用数据(86400000 = 24 小时):

 SELECT order_time+ (86400000 - (order_time % 86400000)) as gap, SUM(quantity) as 
            totalOrdersBetweenInterval
    FROM USAGE_DETAILS ud 
                WHERE order_time >= 1590969600 AND order_time <= 1593388799000 
          
GROUP BY gap 
ORDER BY gap ASC

假设 6 月这个月,我在 1、4、6、7 日收到订单,然后通过使用上面的查询,我能够按如下方式检索数据:

gap | totalOrdersBetweenInterval 
1   | 5
4   | 6
6   | 4
7   | 10

我会在间隙列中收到 UNIX 时间戳,但为了举例,我使用了可读日期。

以上查询将只检索本应收到订单的日期的数据,但我想在如下范围内拆分数据,其中还包括没有订单的日期:

gap | totalOrdersBetweenInterval 
1   | 5
2   | 0
3   | 0
4   | 6
5   | 0
6   | 4
7   | 10
8   | 0
9   | 0
.   | .
.   | .

我该怎么做?

您需要查询 returns 30 rows:1,2,...,6 月的天数。
您可以使用递归 CTE:

with days as (
  select 1 day
  union all
  select day + 1
  from days
  where day < 30
)

但我不确定 Android 是否使用支持 CTEs 的 SQLite 版本。

如果它确实支持它们,您需要做的就是将 CTELEFT 连接加入您的查询:

with 
  days as (
    select 1 day
    union all
    select day + 1
    from days
    where day < 30
  ),
  yourquery as (
    <your query here>
  )
select d.day, coalesce(t.totalOrdersBetweenInterval, 0) totalOrdersBetweenInterval
from days d left join yourquery t
on t.gap = d.day

如果 Android 不支持 CTEs 你将不得不构建 returns 与 UNION ALL:

的查询
select d.day, coalesce(t.totalOrdersBetweenInterval, 0) totalOrdersBetweenInterval
from (
  select 1 day union all select 2 union all
  select 3 union all select 4 union all
  ......................................
  select 29 union all select 30
) d left join (
  <your query here>
) t
on t.gap = d.day 

感谢@forpas 帮助我。 只是发帖以防有人按 unix 时间间隔搜索切片数据。

with 
  days as (
    select 1590969600000 day    --Starting of June 1 2020 
    union all
    select day + 86400000       --equivalent to 1 day 
    from days
    where day < 1593388799000   --Less than 28th of June
  ),
  subquery as (
    SELECT order_time+ (86400000 - (order_time % 86400000)) as gap, SUM(quantity) as 
            totalOrdersBetweenInterval
    FROM USAGE_DETAILS ud 
                WHERE order_time >= 1590969600000 AND order_time <= 1593388799000 
          
    GROUP BY gap 
  )
select d.day, coalesce(t.totalOrdersBetweenInterval, 0) totalOrdersBetweenInterval
from days d left join subquery t
on t.gap = d.day
order by d.day