我在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的所有日期。
我有两个看起来像这样的表:
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查询,我将不胜感激。
答案 0 :(得分:0)
您可以使用递归CTE生成日期列表。如果你cross join
使用飞机,每个飞机每个日期会得到一行。使用left join
,您可以链接测量值(如果存在)。即使未找到任何测量结果,left join
也会离开该行。
例如:
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)