【问题标题】:Does match_recognize have an option to keep all original rows and to flag the matches?match_recognize 是否可以选择保留所有原始行并标记匹配项?
【发布时间】:2019-06-20 16:44:03
【问题描述】:

我想在原始行中添加一个标志,以指示何时找到匹配项。有没有更好的方法只使用 MATCH_RECOGNIZE 而不需要我在下面完成的 RIGHT JOIN?有 6 个匹配项,我想通过在 60 行的原始表中添加一个新列来标记这 6 个匹配项。

WITH match_results AS (
    SELECT *
    FROM Ticker 
    MATCH_RECOGNIZE (
     PARTITION BY symbol
     ORDER BY tstamp
     MEASURES 
      FIRST(down.tstamp) AS start_ts,
      LAST(DOWN.tstamp) AS bottom_ts,
      LAST(UP.tstamp) AS end_ts
     ONE ROW PER MATCH
     AFTER MATCH SKIP PAST LAST ROW
     PATTERN (STRT DOWN+ UP+)
     DEFINE
      DOWN AS price < PREV(price), 
      UP AS price > PREV(price)
    ) MR
    ORDER BY MR.symbol, MR.start_ts
)
SELECT * FROM match_results
RIGHT JOIN ticker 
ON match_results.SYMBOL = ticker.symbol
AND match_results.bottom_ts = ticker.TSTAMP;

这是示例数据:

CREATE TABLE ticker (SYMBOL VARCHAR2(10), tstamp DATE, price NUMBER);

BEGIN
INSERT INTO ticker VALUES('ACME', '01-Apr-11', 12);
INSERT INTO ticker VALUES('GLOBEX', '17-Apr-11', 8);
INSERT INTO ticker VALUES('GLOBEX', '01-Apr-11', 11);
INSERT INTO ticker VALUES('OSCORP', '20-Apr-11', 9);
INSERT INTO ticker VALUES('ACME', '02-Apr-11', 17);
INSERT INTO ticker VALUES('OSCORP', '19-Apr-11', 11);
INSERT INTO ticker VALUES('ACME', '03-Apr-11', 19);
INSERT INTO ticker VALUES('GLOBEX', '03-Apr-11', 13);
INSERT INTO ticker VALUES('OSCORP', '18-Apr-11', 12);
INSERT INTO ticker VALUES('GLOBEX', '02-Apr-11', 12);
INSERT INTO ticker VALUES('ACME', '04-Apr-11', 21);
INSERT INTO ticker VALUES('GLOBEX', '04-Apr-11', 12);
INSERT INTO ticker VALUES('OSCORP', '17-Apr-11', 14);
INSERT INTO ticker VALUES('OSCORP', '15-Apr-11', 12);
INSERT INTO ticker VALUES('OSCORP', '14-Apr-11', 15);
INSERT INTO ticker VALUES('OSCORP', '16-Apr-11', 16);
INSERT INTO ticker VALUES('ACME', '05-Apr-11', 25);
INSERT INTO ticker VALUES('GLOBEX', '05-Apr-11', 11);
INSERT INTO ticker VALUES('ACME', '06-Apr-11', 12);
INSERT INTO ticker VALUES('GLOBEX', '06-Apr-11', 10);
INSERT INTO ticker VALUES('ACME', '07-Apr-11', 15);
INSERT INTO ticker VALUES('GLOBEX', '07-Apr-11', 9);
INSERT INTO ticker VALUES('GLOBEX', '08-Apr-11', 8);
INSERT INTO ticker VALUES('ACME', '08-Apr-11', 20);
INSERT INTO ticker VALUES('OSCORP', '13-Apr-11', 11);
INSERT INTO ticker VALUES('ACME', '13-Apr-11', 25);
INSERT INTO ticker VALUES('ACME', '10-Apr-11', 25);
INSERT INTO ticker VALUES('ACME', '11-Apr-11', 19);
INSERT INTO ticker VALUES('ACME', '09-Apr-11', 24);
INSERT INTO ticker VALUES('GLOBEX', '09-Apr-11', 9);
INSERT INTO ticker VALUES('OSCORP', '12-Apr-11', 12);
INSERT INTO ticker VALUES('GLOBEX', '10-Apr-11', 9);
INSERT INTO ticker VALUES('OSCORP', '11-Apr-11', 15);
INSERT INTO ticker VALUES('GLOBEX', '11-Apr-11', 9);
INSERT INTO ticker VALUES('OSCORP', '10-Apr-11', 15);
INSERT INTO ticker VALUES('ACME', '12-Apr-11', 15);
INSERT INTO ticker VALUES('GLOBEX', '12-Apr-11', 9);
INSERT INTO ticker VALUES('OSCORP', '09-Apr-11', 16);
INSERT INTO ticker VALUES('GLOBEX', '13-Apr-11', 10);
INSERT INTO ticker VALUES('OSCORP', '08-Apr-11', 20);
INSERT INTO ticker VALUES('ACME', '14-Apr-11', 25);
INSERT INTO ticker VALUES('GLOBEX', '14-Apr-11', 11);
INSERT INTO ticker VALUES('OSCORP', '07-Apr-11', 17);
INSERT INTO ticker VALUES('OSCORP', '06-Apr-11', 20);
INSERT INTO ticker VALUES('ACME', '15-Apr-11', 14);
INSERT INTO ticker VALUES('GLOBEX', '15-Apr-11', 12);
INSERT INTO ticker VALUES('ACME', '17-Apr-11', 14);
INSERT INTO ticker VALUES('ACME', '16-Apr-11', 12);
INSERT INTO ticker VALUES('GLOBEX', '16-Apr-11', 11);
INSERT INTO ticker VALUES('OSCORP', '05-Apr-11', 17);
INSERT INTO ticker VALUES('ACME', '18-Apr-11', 24);
INSERT INTO ticker VALUES('GLOBEX', '18-Apr-11', 7);
INSERT INTO ticker VALUES('OSCORP', '04-Apr-11', 18);
INSERT INTO ticker VALUES('OSCORP', '03-Apr-11', 19);
INSERT INTO ticker VALUES('ACME', '19-Apr-11', 23);
INSERT INTO ticker VALUES('GLOBEX', '19-Apr-11', 5);
INSERT INTO ticker VALUES('OSCORP', '02-Apr-11', 22);
INSERT INTO ticker VALUES('ACME', '20-Apr-11', 22);
INSERT INTO ticker VALUES('GLOBEX', '20-Apr-11', 3);
INSERT INTO ticker VALUES('OSCORP', '01-Apr-11', 22);

commit;
END;

这是我的结果:

【问题讨论】:

    标签: sql oracle match-recognize


    【解决方案1】:

    你可以使用ALL ROWS PER MATCH SHOW EMPTY MATCHES:

    SELECT *
    FROM Ticker 
    MATCH_RECOGNIZE (
     PARTITION BY symbol
     ORDER BY tstamp
     MEASURES 
      FIRST(down.tstamp) AS start_ts,
      LAST(DOWN.tstamp) AS bottom_ts,
      LAST(UP.tstamp) AS end_ts,
      CLASSIFIER() AS classifier
     ALL ROWS PER MATCH WITH UNMATCHED ROWS
     AFTER MATCH SKIP PAST LAST ROW
     PATTERN (STRT DOWN+ UP+)
     DEFINE
      DOWN AS price < PREV(price), 
      UP AS price > PREV(price)
    ) MR
    ORDER BY MR.symbol, MR.start_ts;
    

    db<>fiddle demo

    【讨论】:

    • 您提供的答案使用 MATCH_RECOGNIZE 没有 RIGHT_JOIN,这就是我所要求的。我仍然无法理解它是如何工作的,并意识到我不知道如何准确地指定问题。现在在这里考虑更多:dbfiddle.uk/…。你会看到我更新了倒数第二个查询。它现在标记了 3 部分模式的最后一个组件。我不明白为什么第一行不是 08-Apr(START_TS)、09-Apr(BOTTOM_TS)、10-Apr(END_TS)。你的方法比我的方法有更多的结果。这是为什么呢?
    • @Bobby I don't understand why the first row is not 08-Apr(START_TS), 09-Apr(BOTTOM_TS), 10-Apr(END_TS). 模式被定义为(STRT DOWN+ UP+) 所以它会尽可能多地减少
    猜你喜欢
    • 2020-11-26
    • 1970-01-01
    • 2016-11-22
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    相关资源
    最近更新 更多