1

MSSQL 2008 R2 で SQL クエリを実行しています。これは常に一貫した結果セットを返す必要があります。つまり、選択した日付範囲内のすべての日付を表示する必要がありますが、日付範囲内の特定の日付のデータベースには行/値がありません。たとえば、id 1 と 2 の値がある場合、2013-07-03 ~ 2013-07-04 の日付は次のようになります。

シナリオ 1

Date-hour, value, id
2013-07-03-1, 10, 1
2013-07-03-2, 12, 1
2013-07-03-...
2013-07-03-24, 9, 1
2013-07-04-1, 10, 1
2013-07-04-2, 10, 1
2013-07-04-...
2013-07-04-24, 10, 1

2013-07-03-1, 11, 2 
2013-07-03-2, 12, 2
2013-07-03-...
2013-07-03-24, 9, 2
2013-07-04-1, 10, 2
2013-07-04-2, 12, 2
2013-07-04-...
2013-07-04-24, 10, 2

ただし、id 2 に 2013-07-04 の値が欠落している場合、通常は次のような結果セットしか取得できません: シナリオ 2

Date-hour, value, id
2013-07-03-1, 10, 1
2013-07-03-2, 12, 1
2013-07-03-...
2013-07-03-24, 9, 1
2013-07-04-1, 10, 1
2013-07-04-2, 10, 1
2013-07-04-...
2013-07-04-24, 10, 1

2013-07-03-1, 11, 2 
2013-07-03-2, 12, 2
2013-07-03-...
2013-07-03-24, 9, 2

シナリオ 2 では、出力に影響を与える一貫性のない結果セットが作成されます。値が欠落している場合でも SQL クエリが常にシナリオ 1 として返されるようにする方法はありますか。少なくとも、日付範囲内の特定の日付に値がない場合は NULL を返します。結果セットが id 1 と 2 を返す場合、id 1 と 2 のすべての日付をカバーする必要があります。ID 1、2、および 3 が返された場合は、ID 1、2、および 3 のすべての日付をカバーする必要があります。

次のような 2 つのテーブルがあります。

tbl_measurement
    id, date, hour1, hour2, ..., hour24

tbl_plane
    planeId, id, maxSpeed

私が実行している SQL クエリは次のようになります。

SELECT DISTINCT hour00_01, hour01_02, mr.date, mr.id, maxSpeed 
FROM tbl_measurement as mr, tbl_plane as p 
WHERE (date >= '2013-07-03' AND date <= '2013-07-04') AND p.id = mr.id 
GROUP BY mr.id, mr.date, hour00_01, hour01_02, p.maxSpeed
ORDER BY mr.id, mr.date 

私はかなり見回してきましたが、おそらくPIVOTテーブルがこれを解決する方法ですか? 助けていただけませんか?この目的のための SQL クエリの書き方を教えていただければ幸いです。

4

1 に答える 1

0

再帰 CTE を使用して、日付のリストを生成できます。飛行機の場合はcross join、飛行機ごとに日付ごとに 1 つの行を取得します。を使用するleft joinと、測定値が存在する場合にリンクできます。left join測定値が見つからなくても、Aは列を離れます。

例えば:

declare @startDt date = '2013-01-01'
declare @endDt date = '2013-06-30'

; with  AllDates as
        (
        select  @startDt as dt
        union all
        select  dateadd(day, 1, dt)
        from    AllDates
        where   dateadd(day, 1, dt) <= @endDt
        )
select  *
from    AllDates ad
cross join
        tbl_plane p
left join
        (
        select  row_number() over (partition by Id, cast([date] as date) order by id) rn
        ,       *
        from    tbl_measurement
        where   m.inputType = 'forecast'
        ) m
on      p.Id = m.Id
        and m.date = ad.dt
        and m.rn = 1 -- Only one per day
where   p.planeType = 3
option  (maxrecursion 0)
于 2013-07-15T11:02:18.907 に答える