[英]Multiple join with self join in MySQL and split rows in columns by a row value
我有三个表“ Users”,“ Subjects”和“ Marks”,例如
用户表
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是用户(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; "
好了,阅读答案后,我想发表自己的答案:
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
重要的部分是根据用户标识对所有元素进行分组,以及将结果从表中的行写入另一表中的列的方式。 如@TheShalit答案中所写,实现该目标的方法只是将值分配为列。 问题在于,按用户分组时,您将不得不从中选择很多重要的值(一个不为0的NULL
,既不是NULL
,也不是XD)。 COALESCE
函数可确保您始终返回整数,以防万一给出NULL
。
同样重要的是要注意,您必须使用主题名称和数据库中的ID来构建SQL,因为SQL无法检索元素的名称以直接将它们写为列的名称。 这就是为什么我写“ Chem”,“ Phys”和“ Eng”而不是正确的名称的原因。 实际上,如果您只写主题的ID而不是名称,那会更容易,以便稍后在提取行时检索元素。
考虑到非常重要的一点,您的表将在那里具有正确的索引。 请确保你有一个UNIQUE
的表ID marks
与用户和对象,以避免多个值存储在那里
使用这样的选择(按学生加入和分组):
MAX(If(subjects.name="Chemistry",marks.marks,'')) Chemistry,
MAX(If(subjects.name="Physics",marks.marks,'')) Physics,
.....
您将需要执行以下操作:
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个不同的值,但行不同,因此您需要将marks表与自身连接,以便能够将3个不同的记录中的值获取到1个结果行中
我在where子句中为问题中的3个主题使用了您定义为主要ID的值,以确保您获得每个主题的正确结果
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.