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 的所有日期。

我有两个看起来像这样的表:

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使用飞机,则每架飞机的每个日期都会得到一排。使用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 回答