简体   繁体   English

ORACLE GROUP BY with Date 分组不正确

[英]ORACLE GROUP BY with Date does not group correctly

I try to group a given table by date to get a min and max date of member IDs.我尝试按日期对给定的表进行分组以获得成员 ID 的最小和最大日期。 The result should display a time range from when to when a member was part of an OE.结果应显示一个时间范围,从成员何时成为 OE 的一部分。

my given table (excerpt):我给定的表(摘录):

ID  DATE                OE
11  2021-03-06 00:00:00 2926
11  2021-03-07 00:00:00 3879
11  2021-03-08 00:00:00 3879
11  2021-03-09 00:00:00 3879
11  2021-03-10 00:00:00 2926
11  2021-03-11 00:00:00 2926
11  2021-03-12 00:00:00 2926
11  2021-03-13 00:00:00 2926
11  2021-03-14 00:00:00 2926
11  2021-03-15 00:00:00 2926
11  2021-03-16 00:00:00 1344
11  2021-03-17 00:00:00 1344
11  2021-03-18 00:00:00 1344
11  2021-03-19 00:00:00 1344
11  2021-03-20 00:00:00 1344
11  2021-03-21 00:00:00 1344
11  2021-03-22 00:00:00 2926
11  2021-03-23 00:00:00 2926
11  2021-03-24 00:00:00 2926
11  2021-03-25 00:00:00 2926
11  2021-03-26 00:00:00 2926
11  2021-03-27 00:00:00 2926
11  2021-03-28 00:00:00 2926
11  2021-03-29 00:00:00 2926
11  2021-03-30 00:00:00 2926
11  2021-03-31 00:00:00 2926
11  2021-04-01 00:00:00 1549
11  2021-04-02 00:00:00 1549
11  2021-04-03 00:00:00 1549
11  2021-04-04 00:00:00 2926

My Select:我的Select:


    select id, min(date) as mind, max(date) as maxd,OE
    from <table>
    group by id,oe
    order by mind desc;

The output should be something like this: output 应该是这样的:

ID   | MIND                   | MAXD                   | OE
11     2021-04-04 00:00:00      2021-04-04 00:00:00      2926
11     2021-04-01 00:00:00      2021-04-03 00:00:00      1549
11     2021-03-22 00:00:00      2021-03-31 00:00:00      2926
11     2021-03-16 00:00:00      2021-03-21 00:00:00      1344
11     2021-03-10 00:00:00      2021-03-15 00:00:00      2926
11     2021-03-07 00:00:00      2021-03-09 00:00:00      3879
11     2021-03-06 00:00:00      2021-03-06 00:00:00      2926

But it is like this:但它是这样的:

ID   | MIND                   | MAXD                   | OE
11     2021-04-01 00:00:00      2021-04-03 00:00:00      1549
11     2021-03-16 00:00:00      2021-03-21 00:00:00      1344
11     2021-03-07 00:00:00      2021-03-09 00:00:00      3879
11     2021-03-06 00:00:00      2021-04-04 00:00:00      2926

The result should display a time range from when to when a member was part of an OE.结果应显示一个时间范围,从成员何时成为 OE 的一部分。 Even if I add some other IDs (which I obviously have) it does not show the timeline of OE changes in correct order.即使我添加了一些其他 ID(我显然有),它也不会以正确的顺序显示 OE 更改的时间线。

Any help highly appreciated!非常感谢任何帮助!

TIA, TIA,

Michael迈克尔

You can use a trick called tabibitosan to do this kind of grouping:您可以使用一种称为tabibitosan的技巧来进行这种分组:

SELECT id,
       MIN(dt) AS mind,
       MAX(dt) AS maxd,
       oe
FROM   (SELECT id,
               dt,
               oe,
               row_number() OVER (PARTITION BY ID ORDER BY dt) - row_number() OVER (PARTITION BY ID, oe ORDER BY dt) grp
        FROM   your_table)
GROUP  BY id,
          oe,
          grp
ORDER  BY mind DESC;

See this dbfiddle for results查看此 dbfiddle以获取结果

This works by assigning row numbers across the whole set of data (in this case, it's across each id), and then finding the row numbers across the subsets of data (ie across each id and oe), and then subtracting one from the other to form a number you can group by.这是通过在整个数据集中分配行号(在这种情况下,它是跨每个 id),然后找到跨数据子集的行号(即跨每个 id 和 oe),然后从另一个中减去一个来工作的形成一个可以分组的数字。 Consecutive rows get the same group number, but every time there's a non-consecutive row, the group number will change.连续的行获得相同的组号,但每次出现不连续的行时,组号都会改变。

From Oracle 12, you can use MATCH_RECOGNIZE for row-by-row pattern matching:从Oracle 12开始,可以使用MATCH_RECOGNIZE进行逐行模式匹配:

SELECT *
FROM   table_name
MATCH_RECOGNIZE(
  PARTITION BY id
  ORDER     BY "DATE"
  MEASURES
    FIRST(oe)     AS oe,
    FIRST("DATE") AS mind,
    LAST("DATE")  AS maxd
  PATTERN (same_oe+)
  DEFINE
    same_oe AS oe = FIRST(oe)
)

Which, for the sample data:其中,对于示例数据:

CREATE TABLE table_name (ID, "DATE", OE) AS
SELECT 11, DATE '2021-03-06', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-07', 3879 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-08', 3879 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-09', 3879 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-10', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-11', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-12', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-13', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-14', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-15', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-16', 1344 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-17', 1344 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-18', 1344 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-19', 1344 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-20', 1344 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-21', 1344 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-22', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-23', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-24', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-25', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-26', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-27', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-28', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-29', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-30', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-03-31', 2926 FROM DUAL UNION ALL
SELECT 11, DATE '2021-04-01', 1549 FROM DUAL UNION ALL
SELECT 11, DATE '2021-04-02', 1549 FROM DUAL UNION ALL
SELECT 11, DATE '2021-04-03', 1549 FROM DUAL UNION ALL
SELECT 11, DATE '2021-04-04', 2926 FROM DUAL;

Outputs:输出:

ID ID OE原始设备制造商 MIND头脑 MAXD最大
11 11 2926 2926 2021-03-06 00:00:00 2021-03-06 00:00:00 2021-03-06 00:00:00 2021-03-06 00:00:00
11 11 3879 3879 2021-03-07 00:00:00 2021-03-07 00:00:00 2021-03-09 00:00:00 2021-03-09 00:00:00
11 11 2926 2926 2021-03-10 00:00:00 2021-03-10 00:00:00 2021-03-15 00:00:00 2021-03-15 00:00:00
11 11 1344 1344 2021-03-16 00:00:00 2021-03-16 00:00:00 2021-03-21 00:00:00 2021-03-21 00:00:00
11 11 2926 2926 2021-03-22 00:00:00 2021-03-22 00:00:00 2021-03-31 00:00:00 2021-03-31 00:00:00
11 11 1549 1549 2021-04-01 00:00:00 2021-04-01 00:00:00 2021-04-03 00:00:00 2021-04-03 00:00:00
11 11 2926 2926 2021-04-04 00:00:00 2021-04-04 00:00:00 2021-04-04 00:00:00 2021-04-04 00:00:00

fiddle小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM