2013-03-08 58 views
1

我有一个观点,我试图合并两组以不同方式存储的时间序列数据。设置为D每个时间点都有一个与一起存储的值。 Set R的值仅与生效日期,一起存储,并且它们保持有效直至被取代。下面是一个例子表结构:我可以在SQL Server中消除这个子查询吗?

Table D 
---------+------------------+-------- 
D_series | D_time   | D_value 
---------+------------------+-------- 
1  | 2012-01-01 00:00 | 4.52 
1  | 2012-01-01 01:00 | 2.41 
1  | 2012-01-01 02:00 | 5.98 
1  | 2012-01-01 03:00 | 3.51 
2  | 2012-01-01 00:00 | 4.54 
2  | 2012-01-01 01:00 | 6.41 
2  | 2012-01-01 02:00 | 5.28 
2  | 2012-01-01 03:00 | 3.11 
3  | 2012-01-01 00:00 | 4.22 
3  | 2012-01-01 01:00 | 9.41 
3  | 2012-01-01 02:00 | 3.98 
3  | 2012-01-01 03:00 | 3.53 

Table L 
---------+--------- 
D_series | R_series 
---------+--------- 
1  | 1 
2  | 1 
3  | 2 

Table RV 
---------+----------+-------- 
R_series | R_header | R_value 
---------+----------+-------- 
1  | 1  | 5.23 
1  | 2  | 2.98 
2  | 1  | 1.35 

Table RH 
---------+----------------- 
R_header | R_start 
---------+----------------- 
1  | 2012-01-01 00:00 
2  | 2012-01-01 01:49 
3  | 2012-01-01 02:10 

我想,以期D_time返回所有点沿着他们相应的D_value和任何R_value被电流:

---------+------------------+---------+-------- 
D_series | D_time   | D_value | R_value 
---------+------------------+---------+-------- 
1  | 2012-01-01 00:00 | 4.52 | 5.23 
1  | 2012-01-01 01:00 | 2.41 | 5.23 
1  | 2012-01-01 02:00 | 5.98 | 2.98 
1  | 2012-01-01 03:00 | 3.51 | 2.98 
2  | 2012-01-01 00:00 | 4.54 | 5.23 
2  | 2012-01-01 01:00 | 6.41 | 5.23 
2  | 2012-01-01 02:00 | 5.28 | 2.98 
2  | 2012-01-01 03:00 | 3.11 | 2.98 
3  | 2012-01-01 00:00 | 4.22 | 1.35 
3  | 2012-01-01 01:00 | 9.41 | 1.35 
3  | 2012-01-01 02:00 | 3.98 | 1.35 
3  | 2012-01-01 03:00 | 3.53 | 1.35 

我知道我可以,如果我做这样做子查询,并加入到它:

select D.D_series, D_time, D_value, RV1.R_value 
from D 
join L on L.D_series = D.D_series 
join RV RV1 on RV1.R_series = L.R_series 
join RH RH1 on RH1.R_header = RV1.R_header and RH1.R_start <= D.D_time 
left join (
    select R_series, R_value, R_start 
    from RV RV2 
    join RH RH2 on RH2.R_header = RV2.R_header 
) RZ on RZ.R_series = RV1.R_series and RZ.R_start > RH1.R_start 
where RZ.R_start is null or RZ.R_start > D_time 

但据我了解,这个子查询将获取记录在RVRH首先,即使该视图只涉及几个R_series。有没有什么办法可以消除这个子查询并将其变为标准连接?

+0

你可以显示你想要的结果,所以我们不必逆向工程你的单词问题? – 2013-03-08 17:57:28

+1

sqlfiddle会很好。另外,是什么让你觉得每一条记录都会被提取?你看过查询计划吗? – fguchelaar 2013-03-08 18:01:07

+0

@AaronBertrand完成 – Chel 2013-03-08 18:07:44

回答

0

你有没有想过使用交叉应用? “在没有简单连接条件的情况下”他们很擅长。

看到这个答案:When should I use Cross Apply over Inner Join?

在你的情况,我认为这些方针的东西可能的工作:

select D.D_series, D_time, D_value, current_r_values.R_value 
from D 
join L on L.D_series = D.D_series 
cross apply (
    select top 1 R_series, R_value, R_start 
    from RV RV2 
    join RH RH2 on RH2.R_header = RV2.R_header 
    where RH2.R_Start<D.D_time 
    and RV2.R_series = L.R_series 
    order by R.R_Start DESC) current_r_values 

我知道这是不是正是你要找的,但我经常发现使用交叉申请比加入不平等要快得多。

+0

注意:目前我无法访问SQL Server以进行测试,并且在它正常工作之前,我通常必须有几次这样的查询。它的要点是试图为每个D_time获取R_Value,其最新时间比给定的D_time更早。用文字表达这些事情的人很难...... – 2013-03-08 18:26:38

+0

根据执行计划,原始查询每次在'RH'中读取两行(650行)。这似乎是从'RH'获取61250行。这是怎么发生的? – Chel 2013-03-08 18:50:41

+0

该死!我知道我不应该离开sql终端。抱歉!我很可能错过了交叉适用的条件... – 2013-03-08 19:14:56

相关问题