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

oracle互いに1分以内に販売されたアイテムの日付を選択します

    LAGを使用できます / LEAD 前の行と次の行を比較して、現在の行から1分以内かどうかを判断する分析関数:

    SELECT location,
           LISTAGG( equipment_type, ',' )
             WITHIN GROUP ( ORDER BY sold_date )
             AS equipment_types,
           LISTAGG( TO_CHAR( sold_date, 'HH24:MI:SS' ), ',' )
             WITHIN GROUP ( ORDER BY sold_date )
             AS sold_dates
    FROM   (
      SELECT num_cars,
             equipment_type,
             location,
             sold_date,
             CASE
             WHEN within_minute_of_prev = 1 OR within_minute_of_next = 1
             THEN SUM(
                    CASE
                    WHEN within_minute_of_prev = 0 AND within_minute_of_next = 1
                    THEN 1
                    ELSE 0
                    END
                  ) OVER ( PARTITION BY location ORDER BY sold_date )
             END AS grp
      FROM   (
        SELECT c.*,
               CASE
               WHEN ( sold_date
                      - LAG( sold_date ) OVER ( PARTITION BY location ORDER BY sold_date )
                    ) DAY TO SECOND
                    <= INTERVAL '1' MINUTE
               THEN 1
               ELSE 0
               END AS within_minute_of_prev,
               CASE
               WHEN ( LEAD( sold_date ) OVER ( PARTITION BY location ORDER BY sold_date )
                      - sold_date
                    ) DAY TO SECOND
                    <= INTERVAL '1' MINUTE
               THEN 1
               ELSE 0
               END AS within_minute_of_next
        FROM   car_sales c
      )
    )
    WHERE grp IS NOT NULL
    GROUP BY location, grp;
    

    サンプルデータの場合:

    CREATE TABLE CAR_SALES ( NUM_CARS, EQUIPMENT_TYPE, LOCATION, SOLD_DATE ) AS
      SELECT   8, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:00:12' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   1, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:00:45' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   9, 'Jaguars',  'coventry',   DATE '2019-09-07' + INTERVAL '06:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   7, 'Rovers',   'leamington', DATE '2019-08-30' + INTERVAL '13:10:13' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT  10, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '09:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   2, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '13:10:48' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   8, 'Rovers',   'coventry',   DATE '2019-09-06' + INTERVAL '18:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   4, 'Rovers',   'leamington', DATE '2019-09-06' + INTERVAL '09:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT 100, 'Trans Am', 'leamington', DATE '2019-09-06' + INTERVAL '08:59:45' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   1, 'corvette', 'leamington', DATE '2019-09-06' + INTERVAL '09:00:10' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   2, 'Toyota',   'coventry',   DATE '2019-09-06' + INTERVAL '10:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT  15, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '11:05:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   2, 'Jaguars',  'coventry',   DATE '2019-09-07' + INTERVAL '17:02:07' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   3, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '13:10:25' HOUR TO SECOND FROM DUAL;
    

    出力:

    db <> fiddle こちら

    更新

    はるかに短いOracle12cクエリはMATCH_RECOGNIZEを使用します :

    SELECT location,
           LISTAGG( equipment_type, ',' )
             WITHIN GROUP ( ORDER BY sold_date )
             AS equipment_types,
           LISTAGG( TO_CHAR( sold_date, 'HH24:MI:SS' ), ',' )
             WITHIN GROUP ( ORDER BY sold_date )
             AS sold_times
    FROM   car_sales
    MATCH_RECOGNIZE (
       PARTITION BY location
       ORDER BY sold_date
       MEASURES  
          MATCH_NUMBER() AS mno
       ALL ROWS PER MATCH
       PATTERN (A B+)
       DEFINE
          B AS B.sold_date <= PREV(B.sold_date) + interval '1' minute
    )
    GROUP BY location, mno
    ORDER BY location, mno;
    

    これは、テストデータの場合:

    CREATE TABLE CAR_SALES ( NUM_CARS, EQUIPMENT_TYPE, LOCATION, SOLD_DATE ) AS
      SELECT   8, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:00:12' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   1, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:00:45' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   3, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:01:15' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   3, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:01:30' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   9, 'Jaguars',  'coventry',   DATE '2019-09-07' + INTERVAL '06:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   7, 'Rovers',   'leamington', DATE '2019-08-30' + INTERVAL '13:10:13' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT  10, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '09:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   2, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '13:10:48' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   8, 'Rovers',   'coventry',   DATE '2019-09-06' + INTERVAL '18:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   4, 'Rovers',   'leamington', DATE '2019-09-06' + INTERVAL '09:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT 100, 'Trans Am', 'leamington', DATE '2019-09-06' + INTERVAL '08:59:45' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   1, 'corvette', 'leamington', DATE '2019-09-06' + INTERVAL '09:00:10' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   2, 'Toyota',   'coventry',   DATE '2019-09-06' + INTERVAL '10:00:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT  15, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '11:05:00' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   2, 'Jaguars',  'coventry',   DATE '2019-09-07' + INTERVAL '17:02:07' HOUR TO SECOND FROM DUAL UNION ALL
      SELECT   3, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '13:10:25' HOUR TO SECOND FROM DUAL;
    

    出力:

    db <> fiddle こちら



    1. ヒープテーブルへのINSERT…SELECTによる最小限のロギング

    2. テーブル式の基礎、パート4 –派生テーブル、最適化の考慮事項、続き

    3. PythonとMySQLデータベース:実用的な紹介

    4. ルックアップテーブルに従ってデータを置き換える必要があります