2011-03-30 61 views
0

所以我試圖從我已經編寫的幾個MySQL視圖構建一個報表。每個視圖一個有三列,看起來像這樣結合多個視圖中的多個SELECT查詢來統計數據

View ABC: 
------------------------------- 
| A | B | C | 
|   |   |   | 
------------------------------- 
| data1 | asdf | 3 | 
| data1 | jkl; | 1 | 
------------------------------- 

假設有其相同結構的其他三個視圖,命名爲DEF,GHI和JKL。在DEF中,最後一列命名爲D,在GHI中最後一列命名爲E,在JKL中最後一列命名爲F.

在每個視圖中,A列中的值應該相同對於所有行(這是另一種解決我所遇到的問題的方法,它不完全依賴於MySQL,但我確定必須有更好的方法)。

我想要做的是這樣的:

View ABC: 
------------------------------------------------------------- 
| A | B | C | D | E | F | 
|   |   |   |   |   |   | 
------------------------------------------------------------- 
| data1 | asdf | 3 | 0 | 2 | 7 | 
| data1 | jkl; | 1 | 1 | 0 | 0 | 
| data2 | lmno | 0 | 1 | 2 | 17 | 
------------------------------------------------------------- 

所以,我首先想到的是LEFT OUTER JOIN在B場,就像這樣:

SELECT ABC.*, DEF.D, GHI.E, JKL.F 
FROM ABC 
LEFT OUTER JOIN DEF ON ABC.B = DEF.B 
LEFT OUTER JOIN GHI ON ABC.B = GHI.B 
LEFT OUTER JOIN JKL ON ABC.B = JKL.B 

這一切很好,好;它用NULL填充零,我可以很容易地將COALESCE變成0.然而,問題在於如果DEF,GHI或JKL視圖中有一行存在用戶名不匹配ABC的行;該行從我的SELECT中簡單地省略(因爲這是一個左外連接)。 RIGHT OUTER JOIN遭受同樣的問題。

有沒有辦法執行一個完整的外連接,使得在任何四個視圖中出現的任何B在我的SELECT中都有一行?我試過嵌入一些其他選擇,但不幸的是,似乎在SELECT的結果中以不可接受的方式重複行和數據值。從查看文檔,我不認爲MySQL支持一個完整的外連接(至少不是我能找到的),即使這樣做,我也不知道如何從其他視圖獲取用戶名到SELECT語句中的用戶名列。

回答

1

你在找什麼叫做FULL OUTER JOIN。不幸的是,它似乎並沒有直接支持MySQL,但是您可以通過執行UNIONLEFT JOIN s和RIGHT JOIN s來獲得結果。

來源:http://dev.mysql.com/doc/refman/5.0/en/join.html

發佈者Barbarina酒店於2006年下午2點17

9月12日,您可以模擬全外使用(從MySQL 4.0.0上) UNION JOIN:

帶兩張表t1,t2:

SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id 
UNION 
SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id 

三用表T1,T2,T3:

SELECT * 
FROM 
    t1 
    LEFT JOIN t2 ON t1.id = t2.id 
    LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * 
FROM t1 
    RIGHT JOIN t2 ON t1.id = t2.id 
    LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * 
FROM 
    t1 
    RIGHT JOIN t2 ON t1.id = t2.id 
    RIGHT JOIN t3 ON t2.id = t3.id 
+0

再想一想,我想我得出的結論是,一個完整的外部連接實際上不是要走的路,我被迫執行多個選擇並將它們聯合在一起。使用這個邏輯,我能夠產生最終的查詢(我將在另一個答案中發佈,因爲這個評論太長了)。 – wibarr 2011-03-30 01:38:11

0

所以亞當佛朗哥的解決方案實際上是相當接近,但它們都使用LEFT OUTER連接,而不是左,右的組合。鑑於我不得不使用UNION,所有列都必須按順序匹配,所以LEFT和RIGHT OUTER JOIN組合出來了。我設法從他的建議思考的UNION後一起湊齊這一點:

SELECT ABC.B, ABC.C, DEF.D, GHI.E, JKL.F 
FROM ABC 
LEFT OUTER JOIN DEF ON DEF.B = ABC.B 
LEFT OUTER JOIN GHI ON ABC.B = GHI.B 
LEFT OUTER JOIN JKL ON JKL.B = ABC.B 

UNION DISTINCT 

SELECT DEF.B, ABC.C, DEF.D, GHI.E, JKL.F 
FROM `DEF` 
LEFT OUTER JOIN ABC ON DEF.B = ABC.B 
LEFT OUTER JOIN GHI ON DEF.B = GHI.B 
LEFT OUTER JOIN JKL ON JKL.B = DEF.B 

UNION DISTINCT 

SELECT GHI.B, ABC.C, DEF.D, GHI.E, JKL.F 
FROM `GHI` 
LEFT OUTER JOIN ABC ON GHI.B = ABC.B 
LEFT OUTER JOIN DEF ON DEF.B = GHI.B 
LEFT OUTER JOIN JKL ON JKL.B = GHI.B 

UNION DISTINCT 

SELECT ABC.B, ABC.C, DEF.D, GHI.E, JKL.F 
FROM `ABC` 
LEFT OUTER JOIN DEF ON DEF.B = ABC.B 
LEFT OUTER JOIN GHI ON ABC.B = GHI.B 
LEFT OUTER JOIN JKL ON JKL.B = ABC.B 

UNION DISTINCT 

SELECT DEF.B, ABC.D, DEF.D, GHI.E, JKL.F 
FROM `DEF` 
LEFT OUTER JOIN ABC ON DEF.B = ABC.B 
LEFT OUTER JOIN GHI ON DEF.B = GHI.B 
LEFT OUTER JOIN JKL ON JKL.B = DEF.B 

UNION DISTINCT 

SELECT JKL.B, ABC.D, DEF.D, GHI.E, JKL.F 
FROM `JKL` 
LEFT OUTER JOIN ABC ON JKL.B = ABC.B 
LEFT OUTER JOIN DEF ON DEF.B = JKL.B 
LEFT OUTER JOIN GHI ON JKL.B = GHI.B 

我不得不使用UNION DISTINCT以避免被添加重複行,但除此之外,這是非常簡單的。