假设我有3张不同的牌桌。 Foo,Bar和Baz。每个表具有相同的结构;时间戳和数据值。我们还可以假设每个表都在顶行同步。
Foo Bar Baz
________________ ________________ _________________
|Time |Value| |Time |Value| |Time |Value |
|1:00 |0 | |1:00 |10 | |1:00 |100 |
|1:15 |1 | |1:10 |11 | |1:20 |101 |
|1:30 |2 | |1:40 |12 | |1:50 |102 |
|1:45 |3 | |1:50 |13 | |1:55 |103 |
是否有一种简单的方法可以将这些记录组合到一个视图中,其中每列的值被假定为每个列的最后一个已知值填充未提供的时间?
________________________________________
|Time |Foo.Value|Bar.Value|Baz.Value|
|1:00 | 1| 10| 100|
|1:10 | 1| 11| 100|
|1:15 | 2| 11| 100|
|1:20 | 2| 11| 101|
|1:30 | 3| 11| 101|
|1:40 | 3| 12| 101|
|1:45 | 4| 12| 101|
|1:50 | 4| 13| 102|
|1:55 | 4| 13| 103|
编辑:
如果我想选择一个时间范围,但希望提出每列的最后已知值,该怎么办?是否有一种简单的方法可以在不生成整个表格的情况下将其过滤掉?
e.g。如果我想要从1:17到1:48的记录,我会想要以下......
________________________________________
|Time |Foo.Value|Bar.Value|Baz.Value|
|1:20 | 2| 11| 101|
|1:30 | 3| 11| 101|
|1:40 | 3| 12| 101|
|1:45 | 4| 12| 101|
答案 0 :(得分:2)
SQL Server 2008不支持lag()
,更不用lag()
ignore nulls
了。所以,我认为最简单的方法可能是相关的子查询。从三个表中获取所有时间,然后填充值:
select fbb.time,
(select top 1 value from foo t where t.time <= fbb.time order by t.time desc
) as foo,
(select top 1 value from bar t where t.time <= fbb.time order by t.time desc
) as bar,
(select top 1 value from baz t where t.time <= fbb.time order by t.time desc
) as baz
from (select time from foo union
select time from bar union
select time from baz
) fbb;
编辑:
另一种方法是使用聚合:
select time, max(foo) as foo, max(bar) as bar, max(baz) as baz
from (select time, value as foo, NULL as bar, NULL as baz from foo union all
select time, NULL, value, NULL from bar union all
select time, NULL, NULL baz from baz
) fbb
group by time
order by time;
这可能比第一种方法具有更好的性能。
答案 1 :(得分:1)
当您使用SQL SERVER 2008时,这是另一种替代解决方案:
SELECT *
FROM (
SELECT t, [time], value
FROM ( SELECT 'Foo' as t, *
FROM @Foo
UNION
SELECT 'Bar' as t, *
FROM @Bar
UNION
SELECT 'Baz' as t, *
FROM @Baz
) un
WHERE [time] BETWEEN '1:17' AND '1:48'
) AS fbb
PIVOT (MAX(value) FOR fbb.[t] IN (Foo, Bar, Baz)) pvt