两个不同表上的group_concat在第二个表上给出重复的结果

时间:2012-03-07 14:17:43

标签: mysql left-join group-concat

将三个实体视为学生,课程,科目 以下是协会 -

student has_many courses,
student has_many subjects.

现在我想使用mysql group_concat,主题名称和课程名称,在课程上左连接,在主题上左联接以及group_by student_id获取学生记录。

问题是group_concat('subjects.name') as subject_names给了我重复的主题条目,但group_concat('students.name') as student_names给出了唯一的名称。

为什么??

3 个答案:

答案 0 :(得分:9)

2个左连接是通过每个学生的子行的笛卡尔积乘以行

实施例

  • 学生1有3门课程和2门科目
  • 为学生1生成6行
  • 每个主题给出一个course个值=每个课程重复两次
  • 每个课程提供一个subject个值=每个主题重复三次

修复:

选项1:根据MySQL docs

使用GROUP_CONCAT(DISTINCT ...)
  

在MySQL中,您可以获得表达式组合的连接值。要消除重复值,请使用DISTINCT子句。

选项2:使用UNION ALL +派生表

SELECT
    Student, MAX(CourseConcat), MAX(SubjectConcat)
FROM
    (
    -- 2 separate SELECTs here
    .. student LEFT JOIN course ...
    UNION ALL
    .. student LEFT JOIN subjects...
    ) T
GROUP BY
   Student

第二个选项可能更好,虽然更复杂,因为你有 less 中间行要用DISTINCT进行处理

答案 1 :(得分:0)

按照您的逻辑,group_concat('subjects.name') as subject_names会为您提供重复的条目,因为每个学生可能有超过1个主题,因此您将获得subject表上每个学生记录的重复记录,而{ {1}}(我猜)每位学生有1条记录。

答案 2 :(得分:0)

我知道我可能驾驶这个主题太过分了,但是因为搜索谷歌的答案已经指示我好几次了我想分享我的解决方案,因为有点复杂的类似问题。

gbn指出的GROUP_CONCAT(DISTINCT ...)解决方案非常棒,直到你实际上有多个相等的值或几乎相同的值,如á和

我从查询中遗漏了distinct关键字并用PHP解决了问题。如果你只需要区分á,那么简单array_unique就可以了。

不幸的是,我没有那么幸运,我也有完全相同的价值,我需要保留。考虑从数据库查询group_concat字段中返回的样本值分解为数组:

$values = array( 'Value1','Value1','Value2','Value2','Value2','Value2' );

现在以某种方式区分你要处理多少重复项。我做了以下事情:

$x=0;
$first = reset($values);
while($first === $values[$x]) $x++;

上述解决方案仅在您的实际第一个和第二个值永远不相同时起作用,在我的情况下是真的。如果不是你的情况,请找出其他方法来了解你正在处理多少重复项。 最后,在模数的帮助下取消设置所有额外的值:

foreach($values as $k => $v){
       if($k%$x !== 0) unset($values[$k]);
}

多数民众赞成。现在打印$ values将为您提供:

Array
(
    [0] => Value1
    [2] => Value2
    [4] => Value2
)