【问题标题】:GROUP BY adjacent recordsGROUP BY 相邻记录
【发布时间】:2017-11-08 03:05:52
【问题描述】:

如何按SQLite中的相邻记录对列进行分组?

情况

MCVE 用于 12 表 JOIN-ed SELECT 查询(按多列分组)。

表格

entity_log 存储 value(随着时间的推移;timest 作为 Unix 时间时间戳):

CREATE TABLE entity_log (
   id     INTEGER PRIMARY KEY,
   timest INTEGER,
   entity INTEGER /*REFERENCES entity_table(id)*/,
   value  INTEGER
);

INSERT INTO entity_log (timest, entity, value) VALUES (1510160703, 0, 0);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160704, 0, 0);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160705, 0, 1);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160706, 0, 1);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160707, 0, 1);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160708, 0, 1);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160709, 0, 1);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160710, 0, 1);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160711, 0, 0);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160712, 0, 0);
INSERT INTO entity_log (timest, entity, value) VALUES (1510160713, 0, 0);

查询

按时间顺序排列的value - 出现次数,聚合到min(timest)max(timest)

SELECT
   min(timest) AS timest_first,
   max(timest) AS timest_last,
   value
FROM
   entity_log
WHERE
   entity = 0
GROUP BY
   value
ORDER BY
   timest_last DESC
;

结果

如果某个value重复出现(但不相邻;0,1,0而不是0,0,1),则聚合timest-范围重叠:

timest_first  timest_last  value
........03    ........13   0
........05    ........10   1

目标

通过按时间顺序相邻的记录进一步分组value

timest_first  timest_last  value
........11    ........13   0
........05    ........10   1
........03    ........04   0

【问题讨论】:

    标签: sql sqlite group-by gaps-and-islands


    【解决方案1】:

    如果我对您的理解正确:您想要的是取决于下一条记录中的值的结果。如果value 的值不同,则启动一个新的子组。我们可以从下一组中找到每一行的第一行。为此,我们可以使用基于不等式的自动连接。当然,您的数据的最后一行将丢失,因为它们没有具有不同 value 的下一行。 (也许您可以通过使用 UNION 添加一个带有未来日期且不存在 value 的假行来解决此问题。)

    然后从我们知道每个成员下一组的开始日期的这个数据列表中,我们可以使用 Nextdate 进行分组,以便我们也可以找到该组中的第一个和最后一个日期:

    SELECT Min(Somedate) AS timest_first, Max(Somedate) AS timest_last, value FROM
    (SELECT  t2.Value, t2.timest AS Somedate, Min(t1.timest) AS Nextdate, t1.value as n
     FROM entity_log t1 JOIN entity_log t2
     ON t1.timest > t2.timest
     WHERE t1.value <> t2.value
     GROUP BY t2.timest) s1
    GROUP BY value, Nextdate
    ORDER BY 2 desc 
    

    【讨论】:

    • "你想要的是一个依赖于下一条记录中的值的结果。如果value的值不同,它会启动一个新的子组。"正确的。这对多列 (GROUP BY value, value2, ...) 有何作用?
    • 你会得到WHERE t1.value &lt;&gt; t2.value OR t1.value2 &lt;&gt; t2.value2等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 2012-02-17
    • 2021-01-13
    • 2023-03-17
    • 2016-01-27
    • 2010-12-11
    相关资源
    最近更新 更多