2012-03-07 109 views
1

考虑三个实体的学生,当然,主题 下面是协会 -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给出了唯一的名字。

为什么?

+0

你可以添加你的查询吗? – Java 2012-03-07 14:21:38

回答

8

的2左侧联接经由子行的笛卡尔乘积乘以行每个学生

  • 学生1具有3个疗程和2名受试者
  • 生成6行对学生1
  • 给出一个course每个科目的价值=每个科目重复两次
  • 给出了每个过程一个subject值=每个受试者重复三次

要解决:1

选项:使用GROUP_CONCAT(DISTINCT ...)MySQL docs

在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 

第二个选项可能是虽然更加复杂,因为你必须中间行与DISTINCT

+0

感谢您的详细解答。现在理解了两个不同表上的group_concat是如何工作的。 – 2012-03-07 14:41:52

+0

为''group_concat +1(不同的...)'提示 – Pellizon 2014-05-26 14:38:18

0

处理之后你更好逻辑,group_concat('subjects.name') as subject_names给你重复的项目,因为有可能是为每个学生超过1个对象上,这样你得到的就subject表中的每个学生记录重复的记录,而group_concat('students.name') as student_names(我假设)每个学生有1条记录。

+0

不是实际..我没有has_many关系中的任何重复条目。总是有与学生相关的uniq科目和课程。 – 2012-03-07 14:36:47

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]); 
} 

完蛋了。打印$值现在会给你:

Array 
(
    [0] => Value1 
    [2] => Value2 
    [4] => Value2 
) 
相关问题