2015-09-25 51 views
0

我有兩個表:MySQL的:LEFT JOIN表ON table.id IN()

訂單

+----+------+-------+ 
| id | name | notes | 
+----+------+-------+ 
| 1 | Adam | 1,2 | 
| 2 | Ema |  3 | 
| 3 | Petr | 1,3 | 
+----+------+-------+ 

注意

+----+---------------------+ 
| id | text    | 
+----+---------------------+ 
| 1 | This is first note | 
| 2 | This is second note | 
| 3 | And third note  | 
+----+---------------------+ 

我需要選擇行來自訂單和組concat基於Orders.notes的第二個表中的文本。

如果我用這個語句如預期This is first note;This is second note

SELECT o.name, o.notes 
    ,GROUP_CONCAT(DISTINCT n.text SEPARATOR ';') AS notes_text 
FROM orders o 
LEFT JOIN notes n ON n.id IN (1,2) 
WHERE o.id = 1; 

的結果,如果我用這個說法,我需要,其中notes.id IN(orders.notes)

SELECT o.name, o.notes 
    ,GROUP_CONCAT(DISTINCT n.text SEPARATOR ';') AS notes_text 
FROM orders o 
LEFT JOIN notes n ON n.id IN (o.notes) 
WHERE o.id = 1 

它只返回第一個文本This is first note。爲什麼?

SQLFiddle

+0

你只是問'爲什麼'或者你需要另一個想要的結果? – RubahMalam

+0

我需要使用第二條語句,但期望得到類似於第一條語句的結果。 – hovado

+0

'orders.notes'是這個問題的一個不可擴展的解決方案。你應該把'order_id'放到你的'notes'表中,那麼SQL就會更有意義。 –

回答

3

SQL DBS將 「撕開」 中的一個領域CSV值。這三個片段將解析/執行相同:

... n.id IN (o.notes) 
... n.id IN ('1,2') 
... n.id = '1,2' 

注意引號。 1,2被視爲單一字符串,而不是由逗號分隔的兩個單獨的值。

如果你想使用這個壞表設計(你真的應該正常化),然後使用FIND_IN_SET()來代替。

請注意,這會將您鏈接到MySQL,並且您失去了可移植性。

+0

我知道這是不好的設計,並且明白它是一個字符串,但第二個語句返回第一個音符令人困惑。 – hovado

+0

無論如何FIND_IN_SET()解決這個問題。謝謝 – hovado

+0

'in('1,2')'因爲你正在做一個數字字符串比較,所以mysql會將你的'1,2'字符串轉換成一個數字,它變成簡單的'1'。 –