在MySQL中使用self连接进行多次连接,并按行值拆分列中的行

时间:2015-05-04 11:10:58

标签: mysql

我有三个表“用户”,“主题”和“标记”,如

用户表

id  name
1   A
2   B
3   C
4   D
5   E
6   A
7   B

主题表

id  name
1   Chemistry
2   Physics
3   English
4   Maths
5   History

标记表

u_id是Users(id)的外键,s_id是Subjects的外键(id)

id  u_id    s_id    marks
 1     1       1     60
 2     1       2     70
 3     1       3     80
 4     2       2     80
 5     2       3     44
 6     3       1     50
 7     5       4     50
 8     4       5     50
 9     5       4    100
10     2       5    100

我希望结果像

id  Name    Chemistry Physics English 
1   A       60        70      80
2   B       NULL      80      44
3   3       50        NULL    NULL

使用加入

到目前为止,我只能得到

name    name        marks
A       English     80
A       Physics     70
A       Chemistry   60
B       English     44
B       Physics     80
C       Chemistry   50

使用以下查询

SELECT u.name, s.name , m.marks
FROM Users as u 
RIGHT JOIN Marks as m ON m.u_id = u.id 
LEFT JOIN Subjects as s ON m.s_id = s.id  
WHERE s.name = "English" 
  OR s.name = "Physics" 
  OR s.name = "Chemistry"
ORDER BY u.name; "

3 个答案:

答案 0 :(得分:2)

嗯,看完答案后,我想张贴自己的答案:

SELECT 
  u.id
, u.name

, MAX(IF(s.id = 1, COALESCE(m.mark), 0)) as 'Chem'
, MAX(IF(s.id = 2, COALESCE(m.mark), 0)) as 'Phys'
, MAX(IF(s.id = 3, COALESCE(m.mark), 0)) as 'Eng'

FROM marks m
INNER JOIN subjects s
ON s.id = m.subjects_id
INNER JOIN users u 
ON u.id = m.users_id
GROUP BY u.id

您可以在SqlFiddle:http://sqlfiddle.com/#!9/f567b/1

中检查是否有所需

重要的部分是根据用户ID对所有元素进行分组,以及将结果从表中的行写入另一个表中的列的方式。正如@TheShalit回答所述,实现这一点的方法只是将值指定为列。问题在于,当用户进行分组时,您必须从中选择重要的值(不是NULL,XD的那个值)。 COALESCE函数确保始终返回一个整数,以防万一{1}}。

同样重要的是要注意,您必须使用主题的名称和数据库中的ID来构建SQL,因为SQL无法检索要写入的元素的名称它们直接作为列的名称。这就是为什么我写“Chem',' Phys'和' Eng'而不是正确的名称。事实上,如果你只是写了主题的id而不是名字会更容易,只是在你以后获取行时检索元素。

考虑到非常重要的是您将在那里拥有正确的索引。确保表NULL上有UNIQUE个ID,其中包含用户和主题,以避免存储多个值

答案 1 :(得分:1)

使用像这样的选择(连接和学生分组):

getNav: function(index) {
    return  $(this.nav).filter(function() {
        return $(this).data('img') === index;
    });
});

答案 2 :(得分:0)

您需要执行以下操作:

SELECT u.NAME AS NAME,
       m_e.marks AS english,          
       m_p.marks AS physics,
       m_c.marks AS chemistry
FROM users AS u 
JOIN marks AS m_e ON m_e.u_id = u.id 
JOIN marks AS m_p ON m_p.u_id = u.id 
JOIN marks AS m_c ON m_c.u_id = u.id 
WHERE m_e.s_id = 3 AND m_c.s_id = 1 AND m_p.s_id = 2

您从单个表中获得3个不同的值,但是行不同,因此您需要将标记表与其自身连接,以便能够将3个不同记录中的值转换为1个结果行

我在where子句中使用您在问题中为3个主题定义为主要ID的值,以确保为每个主题获得正确的结果