SQL - 基于序列的Group By - Oracle / Postgre

时间:2017-07-13 17:32:39

标签: sql oracle postgresql group-by sequence

我需要一些帮助。 根据序列执行group by。 我正在使用Oracle或Postgres。

我有以下情况。 ID_SEQ基于equip_idDayStat。创建序列。

我需要对这些序列之间的间隔进行分组。

示例:

EQUIP_ID    DAY         STAT    DATE              ID_SEQ
JSTD123     19/06/2017  ON      19/06/2017 16:39    1
JSTD123     19/06/2017  OFF     19/06/2017 16:41    1
JSTD123     01/07/2017  ON      01/07/2017 13:50    1
JSTD123     01/07/2017  OFF     01/07/2017 13:51    1
JSTD123     01/07/2017  OFF     01/07/2017 14:40    2
JSTD123     01/07/2017  ON      01/07/2017 15:20    1
JSTD123     01/07/2017  ON      01/07/2017 15:20    2
JSTD123     01/07/2017  ON      01/07/2017 15:22    3
JSTD123     01/07/2017  ON      01/07/2017 15:22    4
JSTD123     01/07/2017  ON      01/07/2017 15:23    5
JSTD123     01/07/2017  ON      01/07/2017 15:26    6
JSTD123     01/07/2017  ON      01/07/2017 15:26    7

我希望得到以下结果:

EQUIP_ID    DATE         STAT   START               END
JSTD123     19/06/2017   ON     19/06/2017 16:39    19/06/2017 16:39
JSTD123     19/06/2017   OFF    19/06/2017 16:41    19/06/2017 16:41
JSTD123     01/07/2017   ON     01/07/2017 13:50    01/07/2017 13:50
JSTD123     01/07/2017   OFF    01/07/2017 13:51    01/07/2017 14:40
JSTD123     01/07/2017   ON     01/07/2017 15:20    01/07/2017 15:26

我无法获得类似的输出。

1 个答案:

答案 0 :(得分:1)

我认为这就是你要做的。在给定的日期对具有相同统计数据的连续行进行分组,并获取该组的最小日期和最长日期。

逻辑是通过使用lag获取stat的先前值(每equip_id和day)来分配组,然后使用运行总和在遇到新的stat值时重置。完成此组分配后,您可以使用group by获取每个equip_id,stat,day和grp的最小和最大日期。

SELECT equip_id,
       day,
       stat,
       min(date),
       max(date)
FROM
  (SELECT t.*,
          sum(col) over(partition BY equip_id,day ORDER BY date) AS grp
   FROM
     (SELECT t.*,
      CASE WHEN stat=lag(stat) over(partition BY equip_id,day ORDER BY date) THEN 0 ELSE 1 END AS col
      FROM t
      ) t
   ) t
GROUP BY equip_id,day,stat,grp

Sample Demo