MySQL:为什么GROUP_CONCAT会在我的多连接查询中丢失行?

时间:2013-07-05 08:56:44

标签: mysql left-join inner-join group-concat

我正在尝试从table_m中获取所有行,这些行在table_mi中也有一个索引,我希望得到2行(m.id = 3和m.id = 9) - 但是如果我将GROUP_CONCAT添加到我的选择中,然后我只返回一行。我在这些连接中的某个地方发生过一次事故吗?

查询:

SELECT 
    m.id,
    m.name,
    m.keyword,
    IFNULL(GROUP_CONCAT(r.keyword),'TEST') AS restrictions
FROM 
    table_m AS m 
INNER JOIN
    table_mi as mi ON m.id=mi.m_id
LEFT JOIN
    table_ri as ri ON m.id=ri.m_id
LEFT JOIN
    table_r AS r ON ri.r_id=r.id
WHERE 
    (
        m.id>0
        AND m.active=1  
        AND mi.p_id=0
        AND (mi.pa_id="11" OR (mi.pa_id=0 AND mi.id!=0)) 
        AND mi.u_id=IF((SELECT id FROM table_mi WHERE p_id=0 AND pa_id="11" AND u_id="2")>0,"2",0)
    ) OR mi.id=0 
ORDER BY
    mi.priority;

这就是我得到的结果:

ID  NAME    KEYWORD RESTRICTIONS
9   test_a  key_a   r_key_2,r_key_3,r_key_4

这就是我所期待的:

ID  NAME    KEYWORD RESTRICTIONS
9   test_a  key_a   r_key_2,r_key_3,r_key_4
3   test_b  key_b   TEST

请参阅我在sql小提琴上使用架构的完整示例:http://sqlfiddle.com/#!2/359d9/1

2 个答案:

答案 0 :(得分:3)

GROUP_CONCAT是一个聚合函数。它将带回一行,除非您指定GROUP BY子句(任何不在GROUP BY中的字段都是聚合字段)

在ORDER BY之前添加以下内容: -

GROUP BY m.id,  m.name, m.keyword

那说看起来你可能想要使用CONCAT将2个值加在一起而不是GROUP_CONCAT

另外,如果删除子选择,则SQL可能更容易阅读。假设它正在带回一条记录,那么可能如下

SELECT 
    m.id,
    m.name,
    m.keyword,
    IFNULL(GROUP_CONCAT(r.keyword),'TEST') AS restrictions
FROM 
    table_m AS m 
INNER JOIN
    table_mi as mi ON m.id=mi.m_id
LEFT JOIN
    table_ri as ri ON m.id=ri.m_id
LEFT JOIN
    table_r AS r ON ri.r_id=r.id
LEFT OUTER JOIN 
    table_mi AS mi2 ON mi2.p_id=0 AND mi2.pa_id="11" AND mi2.u_id="2"
WHERE 
    (
        m.id>0
        AND m.active=1  
        AND mi.p_id=0
        AND (mi.pa_id="11" OR (mi.pa_id=0 AND mi.id!=0)) 
        AND mi.u_id=IF(mi2.id >0,"2",0)
    ) OR mi.id=0 
ORDER BY
    mi.priority;

答案 1 :(得分:1)

您不需要GROUP_CONCAT来实现您想要的目标。

而不是:

IFNULL(GROUP_CONCAT(r.keyword),'TEST') AS restrictions

使用

IFNULL(r.keyword,'TEST') AS restrictions

保持查询不变,并在GROUP BY m.id

之前添加ORDER BY