2015-09-25 85 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'。 –