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

SQL - 列の日付に少なくとも部分的に日付範囲が含まれているかどうかを調べる

    これはギャップと島として扱うことができると思います 問題。次の入力データを考えてみましょう:(OP のサンプル データに 2 行追加したものと同じ)

    id  company_id  status_id   effective_date
    -------------------------------------------
    1   10          1           2016-12-15
    2   10          1           2016-12-30 
    3   10          5           2017-02-04
    4   10          4           2017-02-08
    5   11          5           2017-06-05
    6   11          1           2018-04-30
    

    次のクエリを使用できます:

    SELECT t.id, t.company_id, t.status_id, t.effective_date, x.cnt
    FROM company_status_history AS t
    OUTER APPLY 
    (
       SELECT COUNT(*) AS cnt
       FROM company_status_history AS c
       WHERE c.status_id = 1 
             AND c.company_id  = t.company_id 
             AND c.effective_date < t.effective_date
    ) AS x
    ORDER BY company_id, effective_date
    

    取得する:

    id  company_id  status_id   effective_date  grp
    -----------------------------------------------
    1   10          1           2016-12-15      0
    2   10          1           2016-12-30      1
    3   10          5           2017-02-04      2
    4   10          4           2017-02-08      2
    5   11          5           2017-06-05      0
    6   11          1           2018-04-30      0
    

    status = 1 を識別できるようになりました 使用する島:

    ;WITH CTE AS 
    (
        SELECT t.id, t.company_id, t.status_id, t.effective_date, x.cnt
        FROM company_status_history AS t
        OUTER APPLY 
        (
           SELECT COUNT(*) AS cnt
           FROM company_status_history AS c
           WHERE c.status_id = 1 
                 AND c.company_id  = t.company_id 
                 AND c.effective_date < t.effective_date
        ) AS x
    )
    SELECT id, company_id, status_id, effective_date,
           ROW_NUMBER() OVER (PARTITION BY company_id ORDER BY effective_date) - 
           cnt AS grp
    FROM CTE 
    

    出力:

    id  company_id  status_id   effective_date  grp
    -----------------------------------------------
    1   10          1           2016-12-15      1
    2   10          1           2016-12-30      1
    3   10          5           2017-02-04      1
    4   10          4           2017-02-08      2
    5   11          5           2017-06-05      1
    6   11          1           2018-04-30      2
    

    計算フィールド grp これらの島を特定するのに役立ちます:

    ;WITH CTE AS 
    (
        SELECT t.id, t.company_id, t.status_id, t.effective_date, x.cnt
        FROM company_status_history AS t
        OUTER APPLY 
        (
           SELECT COUNT(*) AS cnt
           FROM company_status_history AS c
           WHERE c.status_id = 1 
                 AND c.company_id  = t.company_id 
                 AND c.effective_date < t.effective_date
        ) AS x
    ), CTE2 AS 
    (
       SELECT id, company_id, status_id, effective_date,
              ROW_NUMBER() OVER (PARTITION BY company_id ORDER BY effective_date) - 
              cnt AS grp
       FROM CTE
    )
    SELECT company_id, 
           MIN(effective_date) AS start_date, 
           CASE 
              WHEN COUNT(*) > 1 THEN DATEADD(DAY, -1, MAX(effective_date))
              ELSE MIN(effective_date)
           END AS end_date
    FROM CTE2 
    GROUP BY company_id, grp
    HAVING COUNT(CASE WHEN status_id = 1 THEN 1 END) > 0
    

    出力:

    company_id  start_date  end_date
    -----------------------------------
    10          2016-12-15  2017-02-03 
    11          2018-04-30  2018-04-30 
    

    知りたいのは、指定された間隔と重複する上記のレコードだけです。

    デモはこちら やや複雑な使用例です。



    1. 1つのテーブルから別のテーブルにデータを保存できません

    2. Scalaを使用してMySQLデータベースに接続するにはどうすればよいですか?

    3. 型変換。 CのlibpqのPostgreSQLOID値をどうすればよいですか?

    4. php警告mysql_fetch_assoc