sql >> データベース >  >> RDS >> Oracle

Oraclesqlまたはpl/sql:前の行の値と日付の列に基づいて計算します

    Oracle 12cからは、MATCH_RECOGNIZEを使用して実行できます。 :

    SELECT *
    FROM   table_name
    MATCH_RECOGNIZE(
      PARTITION BY stock
      ORDER     BY cdate
      MEASURES
        CLASSIFIER() AS pttrn
      ALL ROWS PER MATCH
      PATTERN (bullish|bearish|other)
      DEFINE
        bullish AS  PREV(open) > PREV(close)
                AND Close > Open
                AND Close > PREV(High)
                AND Open  < PREV(Low),
        bearish AS  Close < Open
                AND Close < PREV(Close)
                AND Open  < PREV(Close)
                AND PREV(Open) < PREV(Close)
                AND Close > PREV(Open)
                AND Open  < PREV(Close)
    )
    

    サンプルデータの場合:

    CREATE TABLE table_name (Stock, Cdate, Open, High, Low, Close, Volume ) AS
    SELECT 'XYZ', DATE '2021-01-01',  40.00,  40.50,  38.50,  38.80,  83057 FROM DUAL UNION ALL
    SELECT 'XYZ', DATE '2021-01-02',  39.20,  39.20,  37.20,  37.80, 181814 FROM DUAL UNION ALL
    SELECT 'XYZ', DATE '2021-01-03',  38.00,  38.50,  36.50,  37.00, 117378 FROM DUAL UNION ALL
    SELECT 'XYZ', DATE '2021-01-04',  36.00,  36.10,  35.60,  35.70,  93737 FROM DUAL UNION ALL
    SELECT 'XYZ', DATE '2021-01-05',  35.35,  36.80,  35.10,  36.60, 169106 FROM DUAL UNION ALL
    SELECT 'XYZ', DATE '2021-01-06',  36.50,  38.50,  36.50,  38.00, 123179 FROM DUAL UNION ALL
    SELECT 'XYZ', DATE '2021-01-07',  37.50,  39.50,  37.30,  39.40, 282986 FROM DUAL UNION ALL
    SELECT 'XYZ', DATE '2021-01-08',  39.00,  40.50,  38.50,  40.00, 117437 FROM DUAL UNION ALL
    SELECT 'DDD', DATE '2021-01-01', 135.35, 136.80, 135.10, 136.60,  16454 FROM DUAL UNION ALL
    SELECT 'DDD', DATE '2021-01-02', 136.50, 138.50, 136.50, 138.00, 281461 FROM DUAL UNION ALL
    SELECT 'DDD', DATE '2021-01-03', 137.50, 139.50, 137.30, 139.40,  77334 FROM DUAL UNION ALL
    SELECT 'DDD', DATE '2021-01-04', 139.00, 140.50, 138.50, 140.00, 321684 FROM DUAL UNION ALL
    SELECT 'DDD', DATE '2021-01-05', 139.70, 139.80, 139.30, 139.40, 873009 FROM DUAL UNION ALL
    SELECT 'DDD', DATE '2021-01-06', 139.20, 139.20, 137.20, 137.80,  62522 FROM DUAL UNION ALL
    SELECT 'DDD', DATE '2021-01-07', 138.00, 138.50, 136.50, 137.00, 114826 FROM DUAL UNION ALL
    SELECT 'DDD', DATE '2021-01-08', 136.60, 136.80, 135.10, 135.35,  27317 FROM DUAL;
    

    出力:

    LAGを使用することもできます 分析関数(Oracle 12より前に使用可能でした):

    SELECT t.*,
           CASE
           WHEN LAG(open) OVER (PARTITION BY stock ORDER BY cdate)
                > LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Close > Open
           AND  Close > LAG(high) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Open  < LAG(low) OVER (PARTITION BY stock ORDER BY cdate)
           THEN 'BULLISH'
           WHEN Close < Open
           AND  Close < LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Open  < LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  LAG(open) OVER (PARTITION BY stock ORDER BY cdate)
                < LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Close > LAG(open) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Open  < LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           THEN 'BEARISH'
           ELSE 'OTHER'
           END AS pttrn
    FROM   table_name t
    

    (これは同様の出力を提供します。)

    db <> fiddle こちら

    更新:上下の追跡:

    繰り返しますが、これがMATCH_RECOGNIZEです。 対象:

    SELECT *
    FROM   table_name
    MATCH_RECOGNIZE(
      PARTITION BY stock
      ORDER     BY cdate
      MEASURES
        CLASSIFIER() AS pttrn
      ALL ROWS PER MATCH
      PATTERN (^initial_value|bullish|bearish|up|down|other)
      DEFINE
        bullish AS  PREV(open) > PREV(close)
                AND Close > Open
                AND Close > PREV(High)
                AND Open  < PREV(Low),
        bearish AS  Close < Open
                AND Close < PREV(Close)
                AND Open  < PREV(Close)
                AND PREV(Open) < PREV(Close)
                AND Close > PREV(Open)
                AND Open  < PREV(Close),
        up      AS  close > PREV(close)
                AND open  > PREV(open),
        down    AS  close < PREV(close)
                AND open  < PREV(open)
    )
    

    ただし、LAGでも同じことができます。 :

    SELECT t.*,
           CASE
           WHEN ROW_NUMBER() OVER (PARTITION BY stock ORDER BY cdate) = 1
           THEN 'INITIAL_VALUE'
           WHEN LAG(open) OVER (PARTITION BY stock ORDER BY cdate)
                > LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Close > Open
           AND  Close > LAG(high) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Open  < LAG(low) OVER (PARTITION BY stock ORDER BY cdate)
           THEN 'BULLISH'
           WHEN Close < Open
           AND  Close < LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Open  < LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  LAG(open) OVER (PARTITION BY stock ORDER BY cdate)
                < LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Close > LAG(open) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Open  < LAG(close) OVER (PARTITION BY stock ORDER BY cdate)
           THEN 'BEARISH'
           WHEN Close > LAG(Close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Open  > LAG(Open) OVER (PARTITION BY stock ORDER BY cdate)
           THEN 'UP'
           WHEN Close < LAG(Close) OVER (PARTITION BY stock ORDER BY cdate)
           AND  Open  < LAG(Open) OVER (PARTITION BY stock ORDER BY cdate)
           THEN 'DOWN'
           ELSE 'OTHER'
           END AS pttrn
    FROM   table_name t
    

    db <> fiddle こちら




    1. Oracle SQLで重複する行を削除し、最新のエントリを残します

    2. ACIでのCarto/Postgresqlの永続データの設定

    3. PHPで動作するようにメールサーバーを構成する

    4. 同じWebページまたはURLを表示しているユーザーを検出する