【问题标题】:Reference data that could or not exist in MySQLMySQL 中可能存在或不存在的引用数据
【发布时间】:2013-12-26 12:02:22
【问题描述】:

我有这张桌子:

courses: id_course,name_course
users: id_user,nickname_user
teachers: id_teacher,id_course_teacher,id_user_teacher (it has a value 
just in case this teacher is in the table users)

我列出一门课程,其中包含所有教师的列表(带有辅助表):

SELECT c.name_course,group_concat(DISTINCT t.name_teacher) AS teachers 
FROM courses c
LEFT JOIN teachers t ON t.id_course_teacher=c.id_course
WHERE c.id_course='1';
It shows: Course 1: Teacher 1, Teacher 2, Teacher 5.

其中一些老师在另一个表 users 中有个人资料,我还想显示老师的昵称(如果存在):

Course 1: Teacher 1, Teacher 2 (nickname), Teacher 5.

我试过了,但我无法将昵称引用给老师:

SELECT name_course,group_concat(DISTINCT t.name_teacher) AS teachers,
                   group_concat(DISTINCT u.nickname_user) AS nickname 
FROM courses c
LEFT JOIN teachers t ON t.id_course_teacher=c.id_course,
LEFT JOIN users u ON t.id_user_teacher=u.id_user 
WHERE c.id_course='1';
The value of nickname is just "nickname", but I can not reference it 
to the teacher 2.

我做错了什么?我应该在 LEFT JOINS 中进行子查询吗?我对此有点迷茫。谢谢。

InoS Heo 的解决方案(在他的评论中有完整的解释)

我只需要添加这个:

GROUP_CONCAT(DISTINCT CONCAT(t.name_teacher, ':', IF(u.nickname_user IS NULL, 'NULL', u.nickname_user))) AS name_nick_map

所以我在 $row['name_nick_map'] 中有我想要的信息(老师 1:null,teacher 2:nickname2,teacher5:null)

【问题讨论】:

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


    【解决方案1】:

    这是您的架构和数据。 http://www.sqlfiddle.com/#!2/7af94/1 如果您在 sqlfiddle 中发布您的数据,我们将不胜感激。

    我觉得要匹配老师的名字和昵称,你应该去掉GROUP_CONCAT()

    就像这样:

    SELECT name_course, t.name_teacher AS teachers,
                       u.nickname_user AS nickname 
    FROM courses c
    LEFT JOIN teachers t ON t.id_course_teacher=c.id_course
    LEFT JOIN users u ON t.id_user_teacher=u.id_user 
    WHERE c.id_course='c1';
    
    +-------------+----------+-------------+
    | name_course | teachers | nickname    |
    +-------------+----------+-------------+
    | c_name1     | t1_name  | u1_nickname |
    | c_name1     | t2_name  | u2_nickname |
    | c_name1     | t3_name  | NULL        |
    +-------------+----------+-------------+
    

    假设多对多关系,我猜你的数据库设计不是标准化的。

    当教师和课程有多对多关系时,teacher_to_course 表是必需的。

    courses_to_teachers(id_course, id_teacher)
    
    SELECT name_course, t.name_teacher AS teachers,
                   u.nickname_user AS nickname 
    FROM courses c
    LEFT JOIN course_to_teachers ct ON c.id_course = ct.id_course
    LEFT JOIN teachers t ON t.id_teacher = ct.id_teacher
    LEFT JOIN users u ON t.id_user_teacher=u.id_user 
    WHERE c.id_course='c1';
    

    更新

    “我用php展示课程,所以可以创建一个数组array[t1_name=>u1_nickname, t2_name=>u2_nickname, etc...)?”

    意思是,您正在使用GROUP_CONCAT() 来简化这样的数组?我认为没有GROUP_CONCAT()也可以制作。

    无论如何,如果您需要GROUP_CONCAT() 为什么不试试这个? (你可以在这里测试http://www.sqlfiddle.com/#!2/7af94/24/0

    SELECT name_course, GROUP_CONCAT(CONCAT(t.name_teacher, ':', IF(u.nickname_user IS NULL, 'NULL', u.nickname_user))) AS name_nick_map
    FROM courses c
    LEFT JOIN teachers t ON t.id_course_teacher=c.id_course
    LEFT JOIN users u ON t.id_user_teacher=u.id_user 
    WHERE c.id_course='c1'
    GROUP BY name_course;
    +-------------+------------------------------------------------------+
    | name_course | name_nick_map                                        |
    +-------------+------------------------------------------------------+
    | c_name1     | t1_name:u1_nickname,t2_name:u2_nickname,t3_name:NULL |
    +-------------+------------------------------------------------------+
    

    如您所见,"t3_name:NULL" 代表"t3_name has no nickname"

    制作数组

    我想知道你是不是在问这个代码。有以下查询和结果。

    SELECT name_course, t.name_teacher AS teacher, u.nickname_user AS nickname 
    FROM courses c
    LEFT JOIN teachers t ON t.id_course_teacher=c.id_course
    LEFT JOIN users u ON t.id_user_teacher=u.id_user 
    WHERE c.id_course='c1';
    +-------------+----------+-------------+
    | name_course | teacher  | nickname    |
    +-------------+----------+-------------+
    | c_name1     | t1_name  | u1_nickname |
    | c_name1     | t2_name  | u2_nickname |
    | c_name1     | t3_name  | NULL        |
    +-------------+----------+-------------+
    

    制作数组。

    $query = "SELECT ....";
    
    $result = mysqli_query($query);
    
    // error handling omitted
    
    $CONTAINER = Array();
    while ($row = mysqli_fetch_assoc($result))
    {
        $CONTAINER[$row['teacher']] = $row['nickname']; 
    }
    
    print_r($CONTAINER);
    
    mysqli_free_result($result);
    

    可能print_r($CONTAINER) 会产生类似"array[t1_name=>u1_nickname, t2_name=>u2_nickname, etc...)" 的东西

    【讨论】:

    • 是的,我已经对数据库进行了规范化,我只是这样写它以使其更简单(我也使用许多其他表):) 问题是当我执行你的第二个查询时,我只获得一行:name_course (1) |教师 (t1_name,t2_name,t3_name) |昵称(NULL)。我用 php 展示课程,所以可以创建一个数组 $array[t1_name=>u1_nickname, t2_name=>u2_nickname, etc...); ?非常感谢您的宝贵时间。
    • http://www.sqlfiddle.com/#!2/6c743/2 在这里我得到 3 行,但在我的脚本中只有一个,但包含所有数据。否则,我将进行另一个查询以仅显示该信息,但我只是想知道我是否只能通过一个查询来做到这一点。 (大查询显示更多信息,有昵称的老师只是一小部分)。
    • 太棒了……!!!我使用了您的第一个解决方案 GROUP_CONCAT(CONCAT(t.name_teacher....,但我添加了 DISTINCT: GROUP_CONCAT(DISTINCT CONCAT(t.name_teacher... 数组的第二个选项不是必需的;) 再次感谢..感谢您的宝贵时间。
    【解决方案2】:

    您的查询中有一些错误,如果您正确执行,您会得到教师姓名的分组:

    SELECT name_course,group_concat(DISTINCT t.name_teacher) AS teachers,
                       group_concat(DISTINCT u.nickname_user) AS nicknames
    FROM courses c
    LEFT JOIN teachers t ON t.id_course_teacher=c.id_course
    LEFT JOIN users u ON t.id_user_teacher=u.id_user 
    WHERE c.id_course='1';
    

    【讨论】:

    • Gracias por la respuesta, pero fue un error mio al escribir :)
    猜你喜欢
    • 2012-11-10
    • 2011-10-03
    • 2010-09-25
    • 2023-02-04
    • 2012-12-21
    • 2021-05-22
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多