同じテーブルの異なる行を組み合わせる-Postgres

ルイス

従業員の間隔に関する情報を保存するテーブルがあります。それをINTERVAL_TABLEと呼びましょう。

ユーザーがインターバルを開始したときと終了したときに保存します。ユーザーは、インターバルを好きなだけ開始し、好きなだけ終了することができます。

これはINTERVAL_TABLE:の単純化された構造です

   INTERVAL_ID | USER_ID | INTERVAL_TYPE_ID | INTERVAL_TIMESTAMP | ENTRY_TYPE

ユーザーは、次のエントリをテーブルに持つことができます。

テーブルの可能なエントリ

次に、同じユーザーと間隔タイプを参照するそのテーブルの異なるエントリを組み合わせたレポートを作成する必要があります。開始と終了のある間隔を識別し、これら2つを1行にグループ化できるはずです。上の画像のデータを想定すると、レポートの出力は次のようになります。

期待される出力を報告する

上の画像のように、出力は日付順に並べる必要があります。

そのためのクエリを作成する方法がわかりません。

ありがとう!

編集-追加情報:

任意のINIT間隔のEND間隔を見つけるには、その間隔のタイムスタンプに基づいて最も近いEND間隔を見つける必要があります。これにより、ID1をID3ではなくID2と一致させる必要があることがわかります。

INIT間隔の後に(タイムスタンプに基づいて)別のINIT間隔が続く場合、そのINITのENDの検索に進むべきではないことに注意することが重要です。これは、これがENDのないINITであるためです。

ウラジミールバラノフ

それはLEADLAG機能を使用して簡単かつ効率的に行うことができます少なくとも、テーブルの自己結合よりもはるかに効率的です:O(n)vs O(n*n)

使用して次のおよび前の行の最初の追加列にLEAD及びLAG適切有しますPARTITION BY

次に、2セットのペアを作成します。1つINIT_INTERVAL目はEND_INTERVALで始まり、2つ目はで終わります。InitとEndの両方を持つペアがある場合、それは2回含まれ、後で削除されUNIONます。

SQLフィドル

サンプルデータ(これは、スクリーンショットに加えて質問に含める必要があるものです)

CREATE TABLE INTERVAL_TABLE (
  INTERVAL_ID int,
  USER_ID int,
  INTERVAL_TYPE_ID int,
  INTERVAL_TIMESTAMP timestamp,
  ENTRY_TYPE varchar(255));

INSERT INTO INTERVAL_TABLE (INTERVAL_ID, USER_ID, INTERVAL_TYPE_ID, INTERVAL_TIMESTAMP, ENTRY_TYPE) VALUES
(1, 1, 1, '2018-03-08 14:00:00', 'INIT_INTERVAL'),
(2, 1, 1, '2018-03-08 15:00:00', 'END_INTERVAL' ),
(3, 1, 1, '2018-03-08 15:30:00', 'END_INTERVAL' ),
(4, 1, 1, '2018-03-08 15:45:00', 'INIT_INTERVAL'),
(5, 1, 1, '2018-03-08 15:50:00', 'INIT_INTERVAL');

クエリ

WITH
CTE
AS
(
  SELECT
    USER_ID
    ,INTERVAL_TYPE_ID
    ,ENTRY_TYPE AS Curr_Entry_Type
    ,INTERVAL_TIMESTAMP AS Curr_Interval_Timestamp
    ,INTERVAL_ID AS Curr_Interval_ID

    ,LAG(ENTRY_TYPE) OVER(PARTITION BY USER_ID, INTERVAL_TYPE_ID ORDER BY INTERVAL_TIMESTAMP) AS Prev_Entry_Type
    ,LAG(INTERVAL_TIMESTAMP) OVER(PARTITION BY USER_ID, INTERVAL_TYPE_ID ORDER BY INTERVAL_TIMESTAMP) AS Prev_Interval_Timestamp
    ,LAG(INTERVAL_ID) OVER(PARTITION BY USER_ID, INTERVAL_TYPE_ID ORDER BY INTERVAL_TIMESTAMP) AS Prev_Interval_ID

    ,LEAD(ENTRY_TYPE) OVER(PARTITION BY USER_ID, INTERVAL_TYPE_ID ORDER BY INTERVAL_TIMESTAMP) AS Next_Entry_Type
    ,LEAD(INTERVAL_TIMESTAMP) OVER(PARTITION BY USER_ID, INTERVAL_TYPE_ID ORDER BY INTERVAL_TIMESTAMP) AS Next_Interval_Timestamp
    ,LEAD(INTERVAL_ID) OVER(PARTITION BY USER_ID, INTERVAL_TYPE_ID ORDER BY INTERVAL_TIMESTAMP) AS Next_Interval_ID
  FROM
    INTERVAL_TABLE
)
,CTE_Result
AS
(
  SELECT
    USER_ID
    ,INTERVAL_TYPE_ID
    ,Curr_Entry_Type AS Entry_Type_Init
    ,Curr_Interval_Timestamp AS Interval_Timestamp_Init
    ,Curr_Interval_ID AS Interval_ID_Init
    ,Next_Entry_Type AS Entry_Type_End
    ,CASE WHEN Next_Entry_Type = 'END_INTERVAL' THEN Next_Interval_Timestamp END AS Interval_Timestamp_End
    ,CASE WHEN Next_Entry_Type = 'END_INTERVAL' THEN Next_Interval_ID END AS Interval_ID_End
  FROM CTE
  WHERE Curr_Entry_Type = 'INIT_INTERVAL'

  UNION -- sic! not UNION ALL

  SELECT
    USER_ID
    ,INTERVAL_TYPE_ID
    ,Prev_Entry_Type AS Entry_Type_Init
    ,CASE WHEN Prev_Entry_Type = 'INIT_INTERVAL' THEN Prev_Interval_Timestamp END AS Interval_Timestamp_Init
    ,CASE WHEN Prev_Entry_Type = 'INIT_INTERVAL' THEN Prev_Interval_ID END AS Interval_ID_Init
    ,Curr_Entry_Type AS Entry_Type_End
    ,Curr_Interval_Timestamp AS Interval_Timestamp_End
    ,Curr_Interval_ID AS Interval_ID_End
  FROM CTE
  WHERE Curr_Entry_Type = 'END_INTERVAL'
)
SELECT
    USER_ID
    ,INTERVAL_TYPE_ID
    ,Interval_Timestamp_Init
    ,Interval_Timestamp_End
    ,Interval_ID_Init
    ,Interval_ID_End
FROM CTE_Result
ORDER BY
  USER_ID
  ,INTERVAL_TYPE_ID
  ,COALESCE(Interval_Timestamp_Init, Interval_Timestamp_End)

結果

| user_id | interval_type_id | interval_timestamp_init | interval_timestamp_end | interval_id_init | interval_id_end |
|---------|------------------|-------------------------|------------------------|------------------|-----------------|
|       1 |                1 |    2018-03-08T14:00:00Z |   2018-03-08T15:00:00Z |                1 |               2 |
|       1 |                1 |                  (null) |   2018-03-08T15:30:00Z |           (null) |               3 |
|       1 |                1 |    2018-03-08T15:45:00Z |                 (null) |                4 |          (null) |
|       1 |                1 |    2018-03-08T15:50:00Z |                 (null) |                5 |          (null) |

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

同じテーブルSQLの行を組み合わせる

分類Dev

Postgresの比較同じ行、カウント、3つの異なるテーブルからの一致

分類Dev

Postgresデータベースのテーブルの単一のJSON列で2つのキーの組み合わせをクエリする

分類Dev

postgresを使用して同じテーブルの列を異なる値で更新します

分類Dev

custiomで定義された変数を組み合わせて、postgresでテーブルのレコードとして表示する方法

分類Dev

同じ属性を持つ2つの異なるテーブルの値を組み合わせる方法

分類Dev

postgresの異なるレコードの同じテーブルに同じデータ(またはコピー)を挿入する方法

分類Dev

異なるテーブルの列を組み合わせる

分類Dev

組み合わせがジャンクションテーブルにすでに存在するかどうかを確認するPostgresクエリ

分類Dev

異なるテーブルを同じ列に曖昧さなく組み合わせる

分類Dev

異なる選択合計クエリを同じテーブルの異なるwhereと組み合わせる(Laravelの方法)

分類Dev

同じ列で値が異なる2つのテーブルを組み合わせて、一致しないテーブルのみを返します

分類Dev

同じテーブルの結合と結合を組み合わせる

分類Dev

同じSQLデータベース内の異なるテーブルのデータとテーブル名を組み合わせる

分類Dev

同じテーブル行で2つのテーブルセルを組み合わせる方法は?

分類Dev

Postgres-これら2つのクエリを組み合わせる

分類Dev

Python:BeautifulSoupは、同じテーブルの異なるテーブルヘッダーを組み合わせます

分類Dev

同じ日付の2つのテーブルを組み合わせる方法

分類Dev

同じテーブルから異なるWHERE句からの2つのSELECTクエリを組み合わせる

分類Dev

列数の異なるテーブルを組み合わせる

分類Dev

列の数は同じで行の数が異なる複数のシートを組み合わせる

分類Dev

繰り返しなしで同じテーブルの組み合わせを作成するoraclesql

分類Dev

PythonスクリプトがPostgresテーブルのすべての行を同じ値として設定するのはなぜですか?

分類Dev

2つの異なるブラウザで同じCSSスタイルを組み合わせる

分類Dev

Postgresは異なるテーブルを更新します

分類Dev

Postgres:複数のJSONBtsvectorを組み合わせたテキスト検索

分類Dev

異なる列を持つ2つの異なるテーブルを組み合わせる方法

分類Dev

複数のテーブルの行を組み合わせる

分類Dev

Postgresの結合テーブルの列ごとに行を並べ替える

Related 関連記事

  1. 1

    同じテーブルSQLの行を組み合わせる

  2. 2

    Postgresの比較同じ行、カウント、3つの異なるテーブルからの一致

  3. 3

    Postgresデータベースのテーブルの単一のJSON列で2つのキーの組み合わせをクエリする

  4. 4

    postgresを使用して同じテーブルの列を異なる値で更新します

  5. 5

    custiomで定義された変数を組み合わせて、postgresでテーブルのレコードとして表示する方法

  6. 6

    同じ属性を持つ2つの異なるテーブルの値を組み合わせる方法

  7. 7

    postgresの異なるレコードの同じテーブルに同じデータ(またはコピー)を挿入する方法

  8. 8

    異なるテーブルの列を組み合わせる

  9. 9

    組み合わせがジャンクションテーブルにすでに存在するかどうかを確認するPostgresクエリ

  10. 10

    異なるテーブルを同じ列に曖昧さなく組み合わせる

  11. 11

    異なる選択合計クエリを同じテーブルの異なるwhereと組み合わせる(Laravelの方法)

  12. 12

    同じ列で値が異なる2つのテーブルを組み合わせて、一致しないテーブルのみを返します

  13. 13

    同じテーブルの結合と結合を組み合わせる

  14. 14

    同じSQLデータベース内の異なるテーブルのデータとテーブル名を組み合わせる

  15. 15

    同じテーブル行で2つのテーブルセルを組み合わせる方法は?

  16. 16

    Postgres-これら2つのクエリを組み合わせる

  17. 17

    Python:BeautifulSoupは、同じテーブルの異なるテーブルヘッダーを組み合わせます

  18. 18

    同じ日付の2つのテーブルを組み合わせる方法

  19. 19

    同じテーブルから異なるWHERE句からの2つのSELECTクエリを組み合わせる

  20. 20

    列数の異なるテーブルを組み合わせる

  21. 21

    列の数は同じで行の数が異なる複数のシートを組み合わせる

  22. 22

    繰り返しなしで同じテーブルの組み合わせを作成するoraclesql

  23. 23

    PythonスクリプトがPostgresテーブルのすべての行を同じ値として設定するのはなぜですか?

  24. 24

    2つの異なるブラウザで同じCSSスタイルを組み合わせる

  25. 25

    Postgresは異なるテーブルを更新します

  26. 26

    Postgres:複数のJSONBtsvectorを組み合わせたテキスト検索

  27. 27

    異なる列を持つ2つの異なるテーブルを組み合わせる方法

  28. 28

    複数のテーブルの行を組み合わせる

  29. 29

    Postgresの結合テーブルの列ごとに行を並べ替える

ホットタグ

アーカイブ