2011-11-23 55 views
0

重複的結果具有被這樣相關的四個表:我如何消除加入SQL語句

TABLE A: 1 to many with TABLE B 
TABLE B: 1 to many with TABLE C 
TABLE D: many to 1 with TABLE B 

我想創建一個結果集,它不包含任何重複。

SELECT A.f1 
     A.f2 
     B.f1 
     C.f1 
     D.f1 
from A LEFT JOIN (B INNER JOIN D on D.fk_b = B.id) on A.id = B.fk_a 
     LEFT JOIN C on C.fk_b = B.id 

有些但不是全部記錄是重複的。只有具有相同FK的TABLE DTABLE B的記錄。

如果有2個相同的D.fk_B字段,那麼我想只選擇第一個。我的INNER JOIN會變成類似於:

B INNER JOIN TOP 1 D on..... 

但這不可能?

謝謝!

+2

如果他們確切的重複,你應該使用'選擇DISTINCT' 。 – Viruzzo

+0

no there not exact duplicates :( – jorrebor

+0

定義你的意思是「不完整的重複」 – onedaywhen

回答

-1

嘗試

SELECT DISTINCT A.f1 
     A.f2 
     B.f1 
     C.f1 
     D.f1 
from A LEFT JOIN (B INNER JOIN D on D.fk_b = B.id) on A.id = B.fk_a 
     LEFT JOIN C on C.fk_b = B.id 

你可以這樣做:

B INNER JOIN TOP 1 D on..... 

像這樣

B INNER JOIN (SELECT TOP 1 fields from table) D ON ... 

試試這個:

SELECT DISTINCT A.f1 
      A.f2 
      B.f1 
      C.f1 
      D.f1 
    from A 
    LEFT JOIN (B INNER JOIN (SELECT DISTINCT fk_b FROM D) D on D.fk_b = B.id) 
     on A.id = B.fk_a 
    LEFT JOIN C on C.fk_b = B.id 
+0

B INNER JOIN(從表中選擇TOP 1字段)D ON ...給我一個語法錯誤(我真的使用「table」還是我的表名?這是D對嗎? – jorrebor

+0

使用您的表名和字段列表 – Sparky

+0

您可以用SQL查詢(從D中選擇top 1)替換表名(在本例中爲D)。然而,你的例子不太清楚,但我會修改答案查詢做我認爲你想要的... – Sparky

-1

看起來你有笛卡爾連接。

你可以嘗試在你的列定義的前面添加DISTINCT,或者你可以這樣子查詢來將錶鏈接在一起。

+0

我想我必須使用子查詢。主要是想知道它是否可以做得更加優雅。 – jorrebor

+0

不怕我的朋友 –

2

假設所討論的結構是近所示波紋管的一個,

Tables

下面的SELECT語句會顯示你剛纔的主鍵,簡單地給一個想法關於什麼數據被返回。

SELECT 
    A.id AS `A_id`, 
    B.id AS `B_id`, 
    COALESCE(C.id, 0) AS `C_id`, 
    COALESCE(
    (SELECT D.id FROM D WHERE D.fk_b = B.id LIMIT 1), 0 
) AS `D_id` 
FROM B 
INNER JOIN A ON (B.fk_a = A.id) 
LEFT JOIN C ON (B.id = C.fk_b); 

這可是你自找的選擇:以上測試

SELECT 
    A.f1 AS `A_f1`, 
    A.f2 AS `A_f2`, 
    B.f1 AS `B_f1`, 
    COALESCE(C.f1, '-') AS `C_f1`, 
    COALESCE(
    (SELECT D.f1 FROM D WHERE D.fk_b = B.id LIMIT 1), '-' 
) AS `D_f1` 
FROM B 
INNER JOIN A ON (B.fk_a = A.id) 
LEFT JOIN C ON (B.id = C.fk_b); 

代碼和工作的罰款在MySQL 5.6