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

列の値の変更をカウントするためのSQLクエリ

    Oracle 12から、MATCH_RECOGNIZEを使用できます。 :

    SELECT cat,
           month,
           COUNT(*)
    FROM   (
      SELECT t.*,
             TRUNC( "DATE", 'MM' ) AS month
      FROM   table_name t
    )
    MATCH_RECOGNIZE(
      PARTITION BY cat, month
      ORDER BY "DATE", version
      ONE ROW PER MATCH
      AFTER MATCH SKIP TO LAST change_code
      PATTERN ( strt change_code )
      DEFINE
        change_code AS change_code.some_code <> strt.some_code
    )
    GROUP BY cat, month
    

    サンプルデータの場合:

    CREATE TABLE table_name ( CAT, NR, "DATE", VERSION, SOME_CODE ) AS
    SELECT 'ABC',   123,    TIMESTAMP '2009-02-19 00:00:00 UTC',    1,  'OPP' FROM DUAL UNION ALL
    SELECT 'ABC',   456,    TIMESTAMP '2009-03-18 00:00:00 UTC',    1,  'ZUM' FROM DUAL UNION ALL
    SELECT 'ABC',   444,    TIMESTAMP '2009-03-18 00:00:00 UTC',    1,  'ZUM' FROM DUAL UNION ALL
    SELECT 'ABC',   444,    TIMESTAMP '2009-03-18 00:00:00 UTC',    2,  'MUZ' FROM DUAL UNION ALL
    SELECT 'ABC',   456,    TIMESTAMP '2009-04-18 00:00:00 UTC',    2,  'XXX' FROM DUAL UNION ALL
    SELECT 'ABC',   456,    TIMESTAMP '2009-04-18 00:00:00 UTC',    3,  'XXX' FROM DUAL UNION ALL
    SELECT 'ABC',   456,    TIMESTAMP '2009-04-18 00:00:00 UTC',    4,  'UIO' FROM DUAL UNION ALL
    SELECT 'ABC',   456,    TIMESTAMP '2009-05-18 00:00:00 UTC',    5,  'RQA' FROM DUAL UNION ALL
    SELECT 'DEF',   637,    TIMESTAMP '2018-02-16 00:00:00 UTC',    1,  'FAW' FROM DUAL UNION ALL
    SELECT 'DEF',   789,    TIMESTAMP '2018-02-17 00:00:00 UTC',    1,  'WER' FROM DUAL UNION ALL
    SELECT 'GHI',   248,    TIMESTAMP '2018-02-17 00:00:00 UTC',    1,  'QWE' FROM DUAL UNION ALL
    SELECT 'GHI',   248,    TIMESTAMP '2019-02-17 00:00:00 UTC',    2,  'PPP' FROM DUAL UNION ALL
    SELECT 'GHI',   357,    TIMESTAMP '2020-02-16 00:00:00 UTC',    1,  'FFF' FROM DUAL UNION ALL
    SELECT 'GHI',   420,    TIMESTAMP '2020-02-16 00:00:00 UTC',    1,  'QDS' FROM DUAL UNION ALL
    SELECT 'GHI',   357,    TIMESTAMP '2020-02-16 00:00:00 UTC',    2,  'GGG' FROM DUAL UNION ALL
    SELECT 'GHI',   357,    TIMESTAMP '2020-02-16 00:00:00 UTC',    3,  'LLL' FROM DUAL UNION ALL
    SELECT 'GHI',   357,    TIMESTAMP '2020-02-16 00:00:00 UTC',    4,  'LLL' FROM DUAL UNION ALL
    SELECT 'GHI',   357,    TIMESTAMP '2020-08-16 00:00:00 UTC',    4,  'FFF' FROM DUAL UNION ALL
    SELECT 'GHI',   357,    TIMESTAMP '2020-10-16 00:00:00 UTC',    5,  'ZZZ' FROM DUAL
    

    出力:

    変更を確認したい場合は、以下を使用できます:

    SELECT *
    FROM   (
      SELECT t.*,
             TRUNC( "DATE", 'MM' ) AS month
      FROM   table_name t
    )
    MATCH_RECOGNIZE(
      PARTITION BY cat, month
      ORDER BY "DATE", version
      MEASURES
        MATCH_NUMBER()     AS mn,
        FIRST( some_code ) AS change_from,
        LAST( some_code )  AS change_to
      ONE ROW PER MATCH
      AFTER MATCH SKIP TO LAST change_code
      PATTERN ( strt change_code )
      DEFINE
        change_code AS change_code.some_code <> strt.some_code
    )
    

    どの出力:

    db <> fiddle こちら

    「1か月以内」の要件が、行が2つの異なる暦月にある場合でも、前の行と変更された行の間に最大1か月の差がある変更が必要な場合(発生する変更だけでなく)同じ暦月に)、次を使用できます:

    SELECT cat,
           TRUNC( change_date, 'MM' ) AS month,
           COUNT(*)
    FROM   table_name
    MATCH_RECOGNIZE(
      PARTITION BY cat
      ORDER BY "DATE", version
      MEASURES
        LAST( "DATE" ) AS change_date
      ONE ROW PER MATCH
      AFTER MATCH SKIP TO LAST change_code
      PATTERN ( strt change_code )
      DEFINE
        change_code AS (
          change_code.some_code <> strt.some_code
          AND MONTHS_BETWEEN( change_code."DATE", strt."DATE" ) <= 1
        )
    )
    GROUP BY cat, TRUNC( change_date, 'MM' )
    

    どの出力:

    db <> fiddle こちら



    1. PDOで複数のクエリを実行すると、どのようにエラーが発生しますか?

    2. mysqlでの合計行数のカウントと列によるグループ化

    3. プライベートメッセージングシステム。各会話の最後のメッセージを一覧表示

    4. OracleのREGEXP_SUBSTR()関数