有人可以用 JOIN 和 LEFT JOIN 帮助我理解以下 SQL 代码吗? (对 SQL 来说真的很新)
Posted
技术标签:
【中文标题】有人可以用 JOIN 和 LEFT JOIN 帮助我理解以下 SQL 代码吗? (对 SQL 来说真的很新)【英文标题】:Can someone help me to understand the following SQL code with JOIN and LEFT JOIN? (Really new to SQL) 【发布时间】:2020-04-30 16:05:29 【问题描述】:有 3 个表:学生表、科目表和考试表。
Students table:
+------------+--------------+
| student_id | student_name |
+------------+--------------+
| 1 | Alice |
| 2 | Bob |
| 13 | John |
| 6 | Alex |
+------------+--------------+
Subjects table:
+--------------+
| subject_name |
+--------------+
| Math |
| Physics |
| Programming |
+--------------+
Examinations table:
+------------+--------------+
| student_id | subject_name |
+------------+--------------+
| 1 | Math |
| 1 | Physics |
| 1 | Programming |
| 2 | Programming |
| 1 | Physics |
| 1 | Math |
| 13 | Math |
| 13 | Programming |
| 13 | Physics |
| 2 | Math |
| 1 | Math |
+------------+--------------+
SQL代码如下:
SELECT s.student_id,s.student_name,b.subject_name,COUNT(e.subject_name) as attended_exams
FROM Students as s
INNER JOIN Subjects as b
LEFT JOIN Examinations as e
ON s.student_id=e.student_id AND b.subject_name=e.subject_name
GROUP BY s.student_id,b.subject_name;
我混淆的部分是INNER JOIN
,因为学生表和主题表没有交集或公共列。我想我的目标是在执行LEFT JOIN
之前直观地理解/想象一张表格。由于我们已经在考试表中包含了所有科目,因此是否有必要包含科目表?真的很感谢帮助!
这实际上是 LeetCode 数据库的一个问题。链接如下:
https://leetcode.com/problems/students-and-examinations/
【问题讨论】:
您的代码将在 Postgres 中返回错误,因为您有两个join
s 并且只有一个 on
子句。
@GordonLinoff 我选择了错误的选项卡。改成mysql了。感谢您指出。
大多数人不想为访问您的问题付费。您应该将其复制并粘贴到您的问题中。您的联接在任何形式的 SQL 中都不正确。我现在就写一个答案,不知道你的问题并从你的数据结构中假设一些事情。
这能回答你的问题吗? How to use mysql JOIN without ON condition?
How to Ask help center 在考虑询问之前请先研究/google。阅读您正在使用的手册重新语法/功能。这也是一个(很明显)常见问题解答。对于代码问题,请提供minimal reproducible example。使您的帖子自成一体。每个帖子问 1 个问题。 PS你说你很困惑,但你不清楚是什么。例如,如果表“没有交集或公共列”怎么办?使用足够的单词、句子和对部分示例的引用。解释您的期望和/或就您没有得到的权威性陈述提出问题。 PSRe query meanings.
【参考方案1】:
你的查询相当于:
SELECT s.student_id, s.student_name, b.subject_name,
COUNT(e.subject_name) as attended_exams
FROM Students s CROSS JOIN
Subjects b LEFT JOIN
Examinations as e
ON s.student_id = e.student_id AND
b.subject_name = e.subject_name
GROUP BY s.student_id, b.subject_name;
MySQL 扩展了JOIN
语法,因此ON
子句是可选的。就个人而言,我认为这是一个非常糟糕的主意。 CROSS JOIN
是 CROSS JOIN
,应该这样指定。
查询的作用是为每个学生/学科组合生成一行。然后计算每个学生在每个科目中参加了多少次考试。
【讨论】:
【参考方案2】:不需要带有主题表的JOIN
。您可能还需要一个 IFNULL()
给 Alex,不幸的是他没有参加任何考试。
试试这个:
SELECT
s.student_id, s.student_name, e.subject_name, IFNULL(COUNT(e.subject_name), 0) as attended_exams
FROM Students as s
LEFT JOIN Examinations as e
ON s.student_id = e.student_id
GROUP BY s.student_id, e.subject_name
;
【讨论】:
Subjects
表中的所有数据都存在于Examinations
表中。无需进行涉及Subjects
表和CROSS JOIN
的低效查询。【参考方案3】:
正如雷纳托刚刚指出的那样,这是学生和学科之间的交叉连接。
其余的只是一种标记学生是否参加该科目考试的方法,因为COUNT
不会计算空值。
【讨论】:
【参考方案4】:在 MySql 中,当使用join
或inner join
时,on
条件是可选的,如果未指定,则查询相当于交叉连接。更详细的解决方案here
【讨论】:
请不要回答重复的问题,标记/关闭它们作为重复。以上是关于有人可以用 JOIN 和 LEFT JOIN 帮助我理解以下 SQL 代码吗? (对 SQL 来说真的很新)的主要内容,如果未能解决你的问题,请参考以下文章
INNER JOIN 和 LEFT SEMI JOIN 的区别
外连接(left join、full join、right join)与内连接(inner join)的区别