(SQL) 将多个增量表组装到一个填充视图中?
(SQL) Assembling multiple tables of deltas into a single populated view?
假设我有 3 个不同的 table。 Foo、Bar 和 Baz。每个 tables 具有相同的结构;时间戳和数据值。我们还可以假设每个 table 在顶行同步。
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 |
是否有一种简单的方法可以将这些记录 assemble 放入单个视图中,其中假定每列的值是每个填充未提供时间的最后已知值?
________________________________________
|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|
编辑:
如果我想要 select 一个时间范围,但希望将每列的最后一个已知值提前,该怎么办?有没有一种简单的方法可以做到这一点而无需生成整个 table 然后将其过滤掉?
例如如果我想要从 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|
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;
这可能比第一种方法有更好的性能。
这是另一个替代解决方案,因为您正在使用 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
假设我有 3 个不同的 table。 Foo、Bar 和 Baz。每个 tables 具有相同的结构;时间戳和数据值。我们还可以假设每个 table 在顶行同步。
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 |
是否有一种简单的方法可以将这些记录 assemble 放入单个视图中,其中假定每列的值是每个填充未提供时间的最后已知值?
________________________________________
|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|
编辑:
如果我想要 select 一个时间范围,但希望将每列的最后一个已知值提前,该怎么办?有没有一种简单的方法可以做到这一点而无需生成整个 table 然后将其过滤掉?
例如如果我想要从 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|
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;
这可能比第一种方法有更好的性能。
这是另一个替代解决方案,因为您正在使用 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