(SQL SERVER 2008) 我在多个表中加上时间戳记以加入主/基表。时间点有时等于基表,但有时不等。
创建表格的代码:
create table base (time float);
create table table2 (time float, val2 char(1));
create table table3 (time float, val3 int);
insert into base values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
insert into table2 values (1, 'a'),(5, 'z'),(6, 'm'),(9, 'b');
insert into table3 values (1.5, 1),(5.3, 10),(5.5, 0),(8.1, 4);
结果集应该是基表中每个记录一行,而其他表中的“最新”值。以前,这些表在Excel中使用Vlookup设置为TRUE“加入”,它从排序表中获取最接近的 - 没有经过的匹配。
最终结果应如下所示:
time | val2 | val3
1 | a | NULL
2 | a | 1
3 | a | 1
4 | a | 1
5 | z | 1
6 | m | 0
7 | m | 0
8 | m | 0
9 | b | 4
10 | b | 4
如何使用SQL语句复制它?
由于目前只有大约100条记录,我会在这里考虑效率。
答案 0 :(得分:3)
最可读的可能是select
子句中的相关子查询:
我通常不是select
中select
的粉丝,但相关子查询确实模仿了Excel vlookup的行为。
Select
b.time,
(Select max(t2.val2) From table2 t2 Where b.time >= t2.time) As val2,
(Select max(t3.val3) From table3 t3 Where b.time >= t3.time) As val3
From
base b
Order By
b.time;
http://sqlfiddle.com/#!3/3545e/18
(感谢Laurence上面的代码和SQL Fiddle。)
使用max
要求值不减少。以下版本无论如何都适用:
select
b.time,
(select top 1 t2.val2 from table2 t2 where b.time >= t2.time order by t2.time Desc) as val2,
(select top 1 t3.val3 from table3 t3 where b.time >= t3.time order by t3.time Desc) as val3
from
base b
答案 1 :(得分:2)
一般原则是使用外连接以确保即使第二个表中没有匹配也能得到结果。然后,您可以使用不等式来限制任何过去的内容,并max
选择剩下的最高值。
对于大型表格而言,这可能效率低下,因为您实际上是在进行t2
和t3
的交叉连接。最好是每个嵌套查询并在之后加入结果:
-- Easier to read
Select
b.time,
max(t2.val2) As val2,
max(t3.val3) As val3
From
base b
left outer join
table2 t2
on b.time >= t2.time
left outer join
table3 t3
on b.time >= t3.time
Group By
b.time
Order By
b.time;
-- Probably faster
Select
n.time,
n.val2,
Max(t3.val3)
From (
Select
b.time,
Max(t2.val2) As val2
From
base b
left outer join
table2 t2
On b.time >= t2.time
Group By
b.time
) n
Left Outer Join
table3 t3
On n.time >= t3.time
Group By
n.time,
n.val2
Order By
n.time;