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

オーバーラップを無視して総分数を求める (カーソルベースの回答を CTE に変換)

    次のクエリは、定義に従って、データ内の期間を検索します。最初に相関サブクエリを使用して、レコードが期間の開始であるかどうか (つまり、以前の期間と重複していないかどうか) を判断します。次に、重複しない期間の開始点である最新の開始点として「periodStart」を割り当てます。

    次の (テストされていない) クエリは、このアプローチを採用しています:

    with TimeWithOverlap as (
         select t.*,
                (case when exists (select * from dbo.Available tbefore where t.availStart > tbefore.availStart and tbefore.availEnd >= t.availStart)
                      then 0
                      else 1
                 end) as IsPeriodStart
         from dbo.Available t 
        ),
        TimeWithPeriodStart as (
         select two.*,
                (select MAX(two1.AvailStart) from TimeWithOverlap two1 where IsPeriodStart = 1 and two1.AvailStart <= two.AvailStart
                ) as periodStart
         from TimeWithOverlap two
        )
    select periodStart, MAX(AvailEnd) as periodEnd
    from TimeWithPeriodStart twps
    group by periodStart;
      

    http://sqlfiddle.com/#!6/3483c/20 (2 番目のクエリ)

    2 つの期間が同時に開始された場合でも、AvailStart の値が同じであるため、機能します。サブクエリが相関しているため、これは中規模のデータセットでもうまく機能しない可能性があります。

    これにアプローチする方法は他にもあります。たとえば、SQL Server 2012 を使用している場合は、より単純な方法を提供する累積合計関数を使用できます。



    1. TSQL-BEGIN .. ENDブロック内でGOを使用する方法は?

    2. PostgreSQLでデータを挿入および削除する方法

    3. MySQL:2つの結果セットの違い

    4. mysql regex_replace:置換で正規表現グループを使用する方法