如何按日期将日期事件关联在一起

时间:2019-10-02 13:55:41

标签: sql oracle

我正在写一个查询来组织汽车零件号的安装和拆卸日期。我想查找所有汽车零件安装的记录,以及如果已从车辆上卸下同一零件的记录,则该记录由VIN标识。我很难将这些事件关联在一起,因为将它们联系在一起的唯一事情就是日期。安装后必须先进行删除,除非先将其删除,否则同一部分不能再进行其他安装。

我能够按事件类型将数据汇总到单独的行中(例如,每次安装都有自己的行,每次删除都有自己的行。

我尝试使用的是按事件类型使用DECODE(),但是它将记录保留在单独的行中。也许这里有COALESCE()可以做些什么,但我不确定。

以下是数据外观的摘要:

part_no | serial_no | car_vin | event_type | event_date
12345   | a1b2c3    | 9876543 | INSTALL    | 01-JAN-2019
12345   | a1b2c3    | 9876543 | REMOVE     | 01-AUG-2019
54321   | t3c4a8    | 9876543 | INSTALL    | 01-MAR-2019
12345   | a1b2c3    | 3456789 | INSTALL    | 01-SEP-2019

这是预期的结果:

part_no | serial_no | car_vin | install_date | remove_date
12345   | a1b2c3    | 9876543 | 01-JAN-2019  | 01-AUG-2019
12345   | a1b2c3    | 3456789 | 01-SEP-2019  |
54321   | t3c4a8    | 9876543 | 01-MAR-2019  |

2 个答案:

答案 0 :(得分:3)

我们可以在此处使用旋转逻辑:

SELECT
    part_no,
    serial_no,
    car_vin,
    MAX(CASE WHEN event_type = 'INSTALL' THEN event_date END) AS install_date,
    MAX(CASE WHEN event_type = 'REMOVE'  THEN event_date END) AS remove_date
FROM yourTable
GROUP BY
    part_no,
    serial_no,
    car_vin
ORDER BY
    part_no;

enter image description here

Demo

这种方法是将键值存储表(基本上就是表)转换成想要查看的输出的典型方法。

答案 1 :(得分:0)

您可以使用SQL for Pattern MatchingMATCH_RECOGNIZE):

WITH t(part_no,serial_no,car_vin,event_type,event_date) AS
    (SELECT 12345, 'a1b2c3', 9876543, 'INSTALL', DATE '2019-01-01' FROM dual
    UNION ALL SELECT 12345, 'a1b2c3', 9876543, 'REMOVE', DATE '2019-08-01' FROM dual
    UNION ALL SELECT 54321, 't3c4a8', 9876543, 'INSTALL', DATE '2019-03-01' FROM dual
    UNION ALL SELECT 12345, 'a1b2c3', 3456789, 'INSTALL', DATE '2019-09-01' FROM dual)
SELECT part_no,serial_no,car_vin, INSTALL_DATE, REMOVE_DATE
FROM t
    MATCH_RECOGNIZE (
        PARTITION BY part_no,serial_no,car_vin
        ORDER BY event_date
        MEASURES 
            FINAL MAX(REMOVE.event_date) AS REMOVE_DATE,
            FINAL MAX(INSTALL.event_date) AS INSTALL_DATE
        PATTERN ( INSTALL REMOVE? )
        DEFINE
            REMOVE AS event_type = 'REMOVE',
            INSTALL AS event_type = 'INSTALL'
    )
ORDER BY part_no, INSTALL_DATE, REMOVE_DATE;


+--------------------------------------------------+
|PART_NO|SERIAL_NO|CAR_VIN|INSTALL_DATE|REMOVE_DATE|
+--------------------------------------------------+
|12345  |a1b2c3   |9876543|01.01.2019  |01.08.2019 |
|12345  |a1b2c3   |3456789|01.09.2019  |           |
|54321  |t3c4a8   |9876543|01.03.2019  |           |
+--------------------------------------------------+

此处的关键条款是PATTERN ( INSTALL REMOVE? )。这意味着,您恰好有一个INSTALL事件,然后是零个或一个REMOVE事件。

如果您可以举办多个安装事件,请使用PATTERN ( INSTALL+ REMOVE? )

如果您可以拥有多个INSTALL事件,还可以有多个REMOVE事件,请使用PATTERN ( INSTALL+ REMOVE* )

您可以简单地添加更多事件,例如订单,处置等