2012-09-20 107 views
0

我有四個表a,b,c,d。在表a我有一對id, name。在表b我有一對idx, idyb.idy來自表a.id。在表c, d我有一對id, value這是有關表b.idx簡單但嵌套的SELECT查詢

我必須執行這樣的查詢:

SELECT c.value, d.value 
FROM a,b,c,d 
WHERE a.name = "test" AND b.idy = a.id AND (c.id = b.idx AND d.id = b.idx) 

的問題是有時有在表中丟失記錄c, d所以AND將返回零條記錄,但我需要的結果,如果有可以參閱cd。此外,我不能使用OR,因爲它也爲兩個表返回其他行。

我想會有一個解決方案,使用UNION甚至只是嵌套SELECT s。我更喜歡不使用JOIN或使用單獨的quires。

在此先感謝!

更新:

之所以使用JOIN是性能避免。我正在處理的結構現在比這個更復雜,所以我確信JOIN在未來的將來我會遇到嚴重的性能問題。

+2

爲什麼你不喜歡的JOIN?這似乎是一個經典的'LEFT JOIN'用例。 – Vikdor

+0

我在原文中解釋了原因 – Mahdi

+1

而實際上您已經在使用JOIN。你認爲'FROM a,b,c,d'是什麼意思?至於性能,「沒有得到正確的結果」看起來像是一個嚴重的性能問題... – LSerni

回答

1

我想你想使用LEFT JOIN

SELECT c.value, d.value 
FROM a 
LEFT JOIN b 
    ON a.id = b.idy 
LEFT JOIN c 
    ON b.idx = c.id 
LEFT JOIN d 
    ON b.idx = d.id 
WHERE a.name = "test" 

使用逗號連接語法是INNER JOIN這就要求記錄所有表中可用。

如果您需要在審查JOIN語法幫助有一個有益的指導:

A Visual Explanation of SQL Joins

+0

謝謝bluefeet!它工作起來並且比'RedFilter'解決方案稍快。你有什麼想法,爲什麼? – Mahdi

1
select c.value, d.value 
from a 
inner join b on b.idy = a.id 
left outer join c on c.id = b.idx 
left outer join d on d.id = b.idx 
where a.name = "test" 
    and coalesce(c.id, d.id) is not null 
+0

謝謝RedFilter,我測試你的查詢,它的工作! :) ...要測試其他答案... – Mahdi

+1

@Mahdi爲了闡明我的查詢的功能,它只返回記錄,其中有一個匹配的表'a' *和*'b',以及匹配要麼'c' *要麼*'d'。 – RedFilter

+0

是的,但它比'bluefeet'查詢稍慢。你知道爲什麼嗎?使用查詢有什麼好處嗎?再次感謝! – Mahdi

1
SELECT c.value, d.value 
FROM a,b,c,d 
WHERE a.name = "test" AND b.idy = a.id AND (c.id = b.idx AND d.id = b.idx) 
UNION 
SELECT c.value, NULL 
FROM a,b,c 
WHERE a.name = "test" AND b.idy = a.id AND c.id = b.idx AND NOT EXISTS(SELECT NULL FROM d where d.id = b.idx) 
UNION 
SELECT NULL, d.value 
FROM a,b,d 
WHERE a.name = "test" AND b.idy = a.id AND d.id = b.idx AND NOT EXISTS(SELECT NULL FROM c where c.id = b.idx) 
+0

謝謝JosephH!你的查詢可以工作,但比別人慢幾倍。但是我知道我要求通過'UNION'或嵌套'SELECT'來完成。無論如何謝謝你! :) – Mahdi

+1

@Mahdi我認爲使用它的主要好處是,當行不存在於c或d中時,可以設置'(NULL)'的值。據我所知,我不認爲這是可能的,如果你正在使用'JOIN' – JosephH

+0

對不起,我不明白它的確切含義。可以請你多解釋一下,謝謝... – Mahdi