【问题标题】:SQLite: Group data within certain time intervalSQLite:在特定时间间隔内对数据进行分组
【发布时间】:2020-06-29 14:45:59
【问题描述】:

我有一个存储订单数据的表:

订单表:

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

order_time 表是 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
.   | .
.   | .

我该怎么做?

【问题讨论】:

标签: sqlite android-sqlite


【解决方案1】:

您需要一个返回 30 行的查询:1,2,...,30 代表 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,您将必须构建返回带有 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 

【讨论】:

  • 您的查询有效,但我的数据集存在一个问题。由于天数/间隙自纪元以来处于 unix 时间戳中,因此我从纪元时间开始获取数据。我所做的是将 (day 1590969600000 和天
  • 天 | totalOrdersBetweenInterval 1 | 0 86400001 | 0 172800001 | 0 . | . . | . . | . 1593043200001| 3 1593129600001| 5
  • 我想通了。我还必须将(选择 1 天)更改为与我的起始月份相同的 unix 时间,即 6 月份的(选择 1590969600000 天)。
【解决方案2】:

感谢 @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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 2023-03-16
    • 2022-12-05
    相关资源
    最近更新 更多