首页 > 解决方案 > mysql join重复行,顺序由引起的问题

问题描述

我正在尝试获取每个班级名称、该班级的学生以及分配给该班级的科目。

在这里,问题是由 引起的ORDER BY,我已分配ORDER BYstudent.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 BYto subject.id,它只显示一个学生(第一行:约翰)。问题出在哪里?subquery不使用或如何解决GROUP_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." | ";
            }
        }

标签: phpmysql

解决方案


您的问题是由所有JOINs 引起的。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来控制组中值的顺序。


推荐阅读