2013-05-07 70 views
3

我有3個(MYSQL)表中,A,B和CSQL連接多個表,而不用返回相同的加盟ID兩次

我想要做的是這樣的:

SELECT * FROM a 
LEFT JOIN b ON b.a_id = a.id 
LEFT JOIN c on c.a_id = a.id 
WHERE a.id = 1; 

我有與B.a_id的乙表4名的條目= 1:

B.id | b.a_id 
1 | 1 
2 | 1 
3 | 1 
4 | 1 

我還具有對C表2名這樣的條目

C.id | C.a_id 
10 | 1 
11 | 1 

返回給8個結果:

C.id | B.id 
10 | 1 
10 | 2 
10 | 3 
10 | 4 
11 | 1 
11 | 2 
11 | 3 
11 | 4 

有沒有辦法得到的結果不重複相同的C和B的對象,多回這樣的事?

C.id | B.id 
10 | 1 
11 | 2 
NULL | 3 
NULL | 4 

換句話說,我想說的是「給我一個映射到A = 1的一切,但不要重複相同的C或B的兩倍」。在我的實際數據中,我將接近10個表格,並將所有連接表格的所有排列組合起來,結果通常爲數千行。

在這裏有一個類似的問題Connecting Multiple Tables in SQL while Limiting Exponential Results,但我想盡量避免內部選擇。我覺得這是一個常見的使用數據庫的應該是

謝謝!

+0

DISTINCT是否適合您? – 2013-05-07 15:56:49

+0

在你理想的返回值中,你是不是把C = 10和B = 1任意放在同一行上?爲什麼?也許C = NULL和B = 1,2,3,4和B = NULL並且C = 1,2會更有意義? – mikey 2013-05-07 15:59:47

+0

我對這個關鍵字很熟悉,但我不確定如何在這裏以一種有用的方式在上下文中使用它。如果我只是做SELECT DISTINCT(*),那不能解決問題。 – user2008476 2013-05-07 16:05:03

回答

1

你想要的是而不是簡單的SQL,你不應該期望它在關係數據庫中很容易。

我建議你把所有的值放在一個列中,並用另一列指定它們來自哪裏。這導致了大量union all類型的查詢:

select 'b' as which, b.id 
from a join b on b.a_id = a.id and a.id = 1 
union all 
select 'c', c.id 
from a join c on c_aid = b.id and a.id = 1 
. . . 

的結果是不正是你想要的。

如果您確實需要將數據放在單獨的列中,那麼您需要使用技巧爲每行分配一個行號。然後,您可以按行號彙總結果。像這樣:

select rn, 
     MAX(case when which = 'b' then id end) as b, 
     MAX(case when which = 'b' then id end) as c 
from (select 'b' as which, b.id, @rn := @rn + 1 as rn 
     from a join b on b.a_id = a.id and a.id = 1 cross join (select @rn := 0) const 
     union all 
     select 'c', c.id, @rn := @rn + 1 as rn 
     from a join c on c_aid = b.id and a.id = 1 cross join (select @rn := 0) const 
    ) t 
group by rn 
1

這是使用SQL檢索數據的基礎;它會檢索完整行中的數據,每行都有相同的列,如SELECT子句中所請求的投影中所定義的那樣。任何時候遇到像SQL這樣的問題,對我有什麼幫助就是問自己三個問題:

  1. 我想要的結果行會是什麼樣子?也就是說,他們會有什麼專欄?
  2. 數據庫將如何知道如何填寫每列?
  3. 數據庫將如何知道要返回哪些行?

回答這些問題對於任何給定的情況下,幫助我退後一步,看看爲什麼一定JOINGROUP BY是造成我的麻煩;一般來說,這是因爲要求數據庫提供一些它根本沒有任何概念的東西。

在你的情況,檢索數據的行,就沒有辦法數據庫給你從表B和多行從表C中多行不給你的那些行的笛卡爾積。如果您不想要重複數據,則必須單獨發出SELECT

在回答上面的問題時表示:每一行都有來自表A的所有數據,並且......呃......什麼?無法將表B和C中的多行合併到任意數量的列中,因此無法工作。無法從B和C返回短行數據,因爲每行都是相同的長度。它必須爲B中的每一行和C中的每一行返回一整行,這就完全給出了你描述的場景。

0

有人可能會使用它,但似乎很容易....

,你可以嘗試以下...

而不是左聯合

SELECT * FROM a 
LEFT JOIN b ON b.a_id = a.id 
LEFT JOIN c on c.a_id = a.id 
WHERE a.id = 1; 

使用下面的內部連接

SELECT * FROM a 
INNER JOIN b ON b.a_id = a.id 
INNER JOIN c on c.a_id = a.id 
WHERE a.id = 1; 

這應該工作...我想..

相關問題