Может ли кто-нибудь помочь мне понять следующий код SQL с помощью JOIN и LEFT JOIN? (Действительно новый для SQL) - PullRequest
1 голос
/ 14 января 2020

Есть 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/

Ответы [ 4 ]

3 голосов
/ 14 января 2020

Ваш запрос эквивалентен:

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 голосов
/ 14 января 2020

В MySql, при использовании join или inner join условие on является необязательным, и, если оно не указано, запрос эквивалентен перекрестному соединению. Более подробное решение здесь

1 голос
/ 14 января 2020

Таблица JOIN с субъектами не нужна. Возможно, вам также понадобится IFNULL() для Алекса, который, к сожалению, не посещал никаких экзаменов.

Попробуйте:

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
;
1 голос
/ 14 января 2020

Как только что заметил Ренато, это перекрестное соединение между студентами и предметами. Остальное - просто способ пометить, сдал ли студент экзамен по этому предмету или нет, поскольку COUNT не будет считать нули.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...