2016-12-07 122 views
2

是這樣的可能(我知道這種說法是不工作的,我試了一下):SELECT * FROM T,其中TX或TY IN(SELECT ID FROM Z)

SELECT * FROM t WHERE t.x OR t.y IN (SELECT id FROM z) 

表T:

|id|x |y 
|1 |101|201 
|2 |102|202 

表Z:

|id | 
|101 | 
|201 | 

並從此表中選擇所有條目,其中屬性x或屬性y包含在表z的id列表中。

我知道我可以做

SELECT * FROM t WHERE t.x IN (SELECT id FROM z) OR t.y IN (SELECT id FROM z) 

但這種感覺就像它是非常低效的,當IN值從一個複雜的子查詢來(當時是在這兩個IN條款相同)。

或者當前的查詢規劃器實現是否足夠聰明,以查看這兩個子查詢是否給出相同的結果並僅執行一次?或者,也許有另一種解決方案,使用我目前看不到的EXISTS?我正在使用Postgres,但我在尋找一個通用的解決方案。

回答

4

使用EXISTS

SELECT * FROM t WHERE exists (SELECT 1 FROM z where z.id in (t.x,t.y)) 
+0

完美的作品...謝謝! – unwichtich

1

如果z是一個複雜的查詢,那麼你可以使用一個CTE來簡化代碼:

WITH z AS (
     . . . 
    ) 
SELECT * 
FROM t 
WHERE t.x IN (SELECT id FROM z) OR t.y IN (SELECT id FROM z); 

您還可以使用JOINEXISTS代替:

SELECT * 
FROM t 
WHERE EXISTS (SELECT 1 
       FROM z 
       WHERE z.id IN (t.x, t.y) 
      ); 

JOIN版本的缺點是行可以乘以z中的重複項。

也就是說,帶有兩個IN表達式的版本可能是最有效的。

0

嘗試...

SELECT t.* FROM t join z on t.x = z.id or t.y = z.id 
+0

這不一定是一樣的東西 –

+0

這可能會導致重複的記錄,如果id在'z'表中重複 –

+0

然後你可以在必要時使用'distinct'。 –

相關問題