这是执行此操作的一种方法:
select t3.Time
, t1Time = case when abs(datediff(ms, t1Below.Time, t3.Time))
<= abs(datediff(ms, t1Above.Time, t3.Time))
then t1Below.Time
else t1Above.Time
end
, t1Value = case when abs(datediff(ms, t1Below.Time, t3.Time))
<= abs(datediff(ms, t1Above.Time, t3.Time))
then t1Below.Value
else t1Above.Value
end
, t2Time = case when abs(datediff(ms, t2Below.Time, t3.Time))
<= abs(datediff(ms, t2Above.Time, t3.Time))
then t2Below.Time
else t2Above.Time
end
, t2Value = case when abs(datediff(ms, t2Below.Time, t3.Time))
<= abs(datediff(ms, t2Above.Time, t3.Time))
then t2Below.Value
else t2Above.Value
end
from t3
outer apply (select top 1 t1Below.*
from t1 t1Below
where t3.Time >= t1Below.Time
order by t1Below.Time desc) t1Below
outer apply (select top 1 t1Above.*
from t1 t1Above
where t3.Time <= t1Above.Time
order by t1Above.Time) t1Above
outer apply (select top 1 t2Below.*
from t2 t2Below
where t3.Time >= t2Below.Time
order by t2Below.Time desc) t2Below
outer apply (select top 1 t2Above.*
from t1 t2Above
where t3.Time <= t2Above.Time
order by t2Above.Time) t2Above
SQL Fiddle with demo.
这种方法在每个 t3 时间之前和之后找到最近的 t1 和 t2 时间/值,然后找出其中的哪一个在select 语句中使用的前/后行。
这种方式的优点是 SQL Server 可以有效地使用索引来获取之前/之后的值;为计算每个 t3 时间使用哪个之前/之后值所做的工作应该通过有效检索之前/之后值来抵消。