2011-08-11 20 views
1

對不起,如果您是版主,並且知道更好的標題,請隨時更改。如何連接表格以便右表值取決於左表中的兩個不同行

說,我們有兩個SQL表

 
intervals   vals  
--------   -------  
since    val   
--------   -------  
1     1   
4     2   
8     3 
20     4   
...    ... 
500    100 

我想打一個加盟,使「因爲」從時間間隔表字段將是一個下界爲「VAL」。並且「自」沒有「val」的值越大,就不會出現。看看我想得到什麼:

 
since val 
-------------- 
1  1 
1  2 
1  3 
4  4 
4  5 
4  6 
4  7 
8  8 
8  9 
..... 

如何在泛型SQL中執行此操作? Postgres專用的解決方案也適用。

+0

來自RhodiumToad的查詢更好。 http://www.postgresql.org/docs/9.0/static/tutorial-window.html – Ketema

回答

2

感謝RhodiumToad #postgresql

SELECT * 
FROM vals v 
JOIN (select since 
       , lead(since) over (order by since) as "end" 
     from intervals) s 
     ON (v.val >= s.since 
      AND ((v.val >= s."end") IS NOT TRUE) 
      ) 
; 
+0

查詢計劃:http://pastebin.com/bX3bywN4 – Ketema

+0

謝謝, Ketema。相當不同的印象。現在我想使用這個解決方案,因爲我的表格非常大,查詢執行時間可以持續數十秒。 – zamza

+0

@zamza:大多數大型數據庫都已經針對窗口函數進行了優化(比如'lead()'),但它們可能會讓新手感到困惑,但是會有性能優勢。這只是一個解決方案,我認爲有一種方法可以進一步優化這個,但是我的測試系統昨天下降了。 – vol7ron

3

與其將其視爲「多行」,可以將其視爲範圍

這你想要做什麼:從上面的查詢

create table intervals (since int); 
create table vals (val int); 
insert into intervals values (1), (4), (8), (20), (500); 
insert into vals values (1), (2), (3), (4), (5), (6), (7), (8), (9), (100); 

輸出:

select i.since, v.val 
from intervals i 
join vals v on v.val between i.since and 
    (select min(since) - 1 from intervals where since > i.since) 
order by 1, 2; 

測試代碼(在POSTGRES作爲每個操作的問題上運行)

1 1 
1 2 
1 3 
4 4 
4 5 
4 6 
4 7 
8 8 
8 9 
20 100 
+1

查詢計劃:http://pastebin.com/r0CNrDYx – Ketema

相關問題