[英]Multiple join with self join in MySQL and split rows in columns by a row value
I have three tables "Users" , "Subjects" and "Marks" like 我有三个表“ Users”,“ Subjects”和“ Marks”,例如
Users Table 用户表
id name
1 A
2 B
3 C
4 D
5 E
6 A
7 B
Subjects Table 科目表
id name
1 Chemistry
2 Physics
3 English
4 Maths
5 History
Marks Table 标记表
u_id is the foreign key of Users (id) and s_id is foreign key of Subjects(id) 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
and I wish for the result to be like 我希望结果能像
id Name Chemistry Physics English
1 A 60 70 80
2 B NULL 80 44
3 3 50 NULL NULL
Using Join 使用加入
So far I have only been able to get 到目前为止,我只能得到
name name marks
A English 80
A Physics 70
A Chemistry 60
B English 44
B Physics 80
C Chemistry 50
Using the following query 使用以下查询
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; "
Well, after reading the answers, I wanted to post my own one: 好了,阅读答案后,我想发表自己的答案:
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
You can check that makes all you want in SqlFiddle: http://sqlfiddle.com/#!9/f567b/1 您可以在SqlFiddle中检查是否满足所有要求: http ://sqlfiddle.com/#!9/f567b/1
The important part is the grouping of all the elements according to the user id, and the way of writing the results from rows in a table to columns in another table. 重要的部分是根据用户标识对所有元素进行分组,以及将结果从表中的行写入另一表中的列的方式。 As written in @TheShalit answer, the way of achieving that is just assigning the value as a column.
如@TheShalit答案中所写,实现该目标的方法只是将值分配为列。 Problem is that when grouping by user, you'll have a lot of values there from where you have to select the important one (the one that is not 0 neither
NULL
, XD). 问题在于,按用户分组时,您将不得不从中选择很多重要的值(一个不为0的
NULL
,既不是NULL
,也不是XD)。 COALESCE
function makes sure that you always return a integer, just in case a NULL
is given. COALESCE
函数可确保您始终返回整数,以防万一给出NULL
。
It's also important to notice that you'll have to build the SQL with the names of the subjects and the ids from database, as SQL can't retrieve the name of the elements to write them directly as names of the columns. 同样重要的是要注意,您必须使用主题名称和数据库中的ID来构建SQL,因为SQL无法检索元素的名称以直接将它们写为列的名称。 That's why I wrote 'Chem', 'Phys' and 'Eng' instead of the right names.
这就是为什么我写“ Chem”,“ Phys”和“ Eng”而不是正确的名称的原因。 In fact, would be easier if you just wrote the id of the subject instead of a name, just to retrieve the elements later when you'll fetch the rows.
实际上,如果您只写主题的ID而不是名称,那会更容易,以便稍后在提取行时检索元素。
Take into account that is VERY IMPORTANT that you'll table will have the right indexes there. 考虑到非常重要的一点,您的表将在那里具有正确的索引。 Make sure you have an
UNIQUE
id on the table marks
with users and subjects to avoid having more than one value there stored 请确保你有一个
UNIQUE
的表ID marks
与用户和对象,以避免多个值存储在那里
Use select like this(with joins and group by student): 使用这样的选择(按学生加入和分组):
MAX(If(subjects.name="Chemistry",marks.marks,'')) Chemistry,
MAX(If(subjects.name="Physics",marks.marks,'')) Physics,
.....
You will need to do something like: 您将需要执行以下操作:
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
You are getting 3 different values from a single table but different rows so you need to join the marks table with itself to be able to get the values from 3 different records into 1 result row 您将从单个表中获取3个不同的值,但行不同,因此您需要将marks表与自身连接,以便能够将3个不同的记录中的值获取到1个结果行中
I used the values that you defined as primary id's for your 3 subjects in your question in the where clause to make sure you are getting the correct result for each subject 我在where子句中为问题中的3个主题使用了您定义为主要ID的值,以确保您获得每个主题的正确结果
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.