mysql join重复行,按问题排序

时间:2018-09-03 10:36:00

标签: php mysql

我正在尝试获取每个班级的名称,该班级的学生以及分配给该班级的主题。

在这里,问题是由ORDER BY引起的,我已将ORDER BY分配给student.id

这会导致主题行重复

如果未分配ORDER BY,则会按预期获取主题行,不是重复的,而是学生行重复的

表结构

学生

id  |   Rid |   class   |   name
================================
1   |   1   |   1       |   John
2   |   2   |   1       |   Harsita

课程

id  |   title
==============
1   |   One
2   |   two
3   |   three

主题

id  |   title
===============
1   |   science
2   |   math
3   |   english
4   |   social
5   |   hpe

class_subject

id  |   class   |   subject
===========================
1   |   1       |   1   
2   |   1       |   2
3   |   1       |   3
4   |   1       |   4

要求为

class: One
Science | Math | English | Social | Hpe | 
John | Harsita 

但是我得到的

如果将ORDER BY分配给student.id

class: One
Science | Math | English | Social | Hpe | Math | English | Social | Hpe | Science | 
John | Harsita |

如果ORDER BY尚未分配给student.id

class: One
Science | Math | English | Social | Hpe | 
John | Harsita | John | Harsita | John | Harsita | John | Harsita | John | Harsita | 

我尝试使用GROUP BYsubject.id,它仅显示一个学生(第一行:John)。问题在哪里?不使用subqueryGROUP_CONCAT

怎么解决

代码-php和mysql(使用ORDER BY)

//mysql query
    SELECT 
        DISTINCT class_subject.class, 
        subject.title AS sub,
        student.name AS stdt,
        class.title AS class
    FROM 
        student
    INNER JOIN class_subject ON class_subject.class=student.class
    INNER JOIN subject ON subject.id=class_subject.subject
    INNER JOIN class ON class.id=student.class
    WHERE
        student.class=:cid;

//php
    $class='';
    $stdt='';
    $sub='';
    $results = Array();
        while($row=$result->fetch(PDO::FETCH_ASSOC)){
            if ($row['class'] != $class){
                $class = $row['class'];
                echo "Class: ".$class."<br/>";
            }
            if ($row['sub'] != $sub){
                $sub = $row['sub'];
                echo $sub." | ";
            }
            $results[]=$row;
        }
        echo "<br/>";
        foreach ($results as $row) {
            if ($row['stdt'] != $stdt) {
                $stdt = $row['stdt'];
                echo $stdt." | ";
            }
        }

2 个答案:

答案 0 :(得分:1)

您的问题是由所有JOIN引起的。与第1班相关的4个科目和2个学生。因此您的结果将得到4 * 2 = 8行。如您所见,加入的结果将是4个学科名称中的2组或2个学生名称中的4组。您可以选择在PHP代码中处理此问题,或者由于无论如何都在有效地对PHP代码进行分组,因此请在查询中进行分组:

SELECT 
    c.title AS class,
    GROUP_CONCAT(DISTINCT s.title ORDER BY s.title SEPARATOR ' | ') AS subjects,
    GROUP_CONCAT(DISTINCT t.name ORDER BY t.name SEPARATOR ' | ') AS students
FROM class c
JOIN class_subject cs ON cs.class=c.id
JOIN subject s ON s.id=cs.subject
JOIN student t ON c.id=t.class
WHERE c.id=1
GROUP BY class

输出:

class   subjects                            students
One     english | math | science | social   Harsita | John

请注意,您可以在ORDER BY内指定GROUP_CONCAT,以控制组中值的顺序。

答案 1 :(得分:1)

根据您的预期结果,似乎您需要名称和主题的汇总结果

SELECT 
    group_concat( subject.title) AS sub,
    group_concat(student.name) AS stdt,
    class.title AS class
FROM 
    student
INNER JOIN class_subject ON class_subject.class=student.class
INNER JOIN subject ON subject.id=class_subject.subject
INNER JOIN class ON class.id=student.class
WHERE student.class=:cid
group by class.title

使用聚集功能和分组,您可以在同一行上显示汇总结果