2016-04-07 4 views
1

У меня есть три таблицы. Два из них - отдельные нерелевантные таблицы (студенты и субъекты), третий (записи) - это тот, который связывает их как с внешними ключами (student_id, так и subject_id).MySQL Выбор всех записей из одной таблицы и их совпадений/NULL из другой таблицы

Вот все таблицы с записями:

студентов:

+------------+------------+-----------+---------------------+---------------------+ 
| student_id | first_name | surname | email    | reg_date   | 
+------------+------------+-----------+---------------------+---------------------+ 
|   1 | Emily  | Jackson | [email protected] | 2012-10-14 11:14:13 | 
|   2 | Daniel  | ALexander | [email protected] | 2014-08-19 08:08:23 | 
|   3 | Sarah  | Bell  | [email protected]  | 1998-07-04 13:16:32 | 
|   4 | Alex  | Harte  | [email protected] | 1982-06-14 00:00:00 | 
+------------+------------+-----------+---------------------+---------------------+  

предметы:

+------------+--------------+------------+----------------+ 
| subject_id | subject_name | exam_board | level_of_entry | 
+------------+--------------+------------+----------------+ 
|   1 | Art   | CCEA  | AS    | 
|   2 | Biology  | CCEA  | A    | 
|   3 | Computing | OCR  | GCSE   | 
|   4 | French  | CCEA  | GCSE   | 
|   5 | Maths  | OCR  | AS    | 
|   6 | Chemistry | CCEA  | GCSE   | 
|   7 | Physics  | OCR  | AS    | 
|   8 | RS   | CCEA  | GCSE   | 
+------------+--------------+------------+----------------+  

записей:

+----------+---------------+---------------+------------+ 
| entry_id | student_id_fk | subject_id_fk | entry_date | 
+----------+---------------+---------------+------------+ 
|  1 |    1 |    1 | 2012-10-15 | 
|  2 |    1 |    4 | 2011-09-21 | 
|  3 |    1 |    3 | 2015-08-10 | 
|  4 |    2 |    6 | 1992-07-13 | 
|  5 |    3 |    7 | 2013-02-12 | 
|  6 |    3 |    8 | 2016-01-14 | 
+----------+---------------+---------------+------------+ 

Как бы идти о выборе имена o f все учащиеся (students.first_name) и имя (subjects.subject_name) от того, что у них есть? Я имею в виду, что все имена учеников возвращаются, и все имена субъектов для их записей перечислены рядом с ними, с NULL для тех, у кого нет записей. Я также хочу, чтобы он был сгруппирован по первому имени в алфавитном порядке.

Я хочу выход быть что-то вроде:

first_name subject_name 
-------------------------- 
Alex   NULL 
Daniel  Chemistry 
Emily   French 
Emily   Computing 
Sarah   Physics 
Sarah   RS 

хотя я не уверен, что это совершенно правильно.

Я думаю, это так:

SELECT students.first_name, subjects.subject_name 
FROM students 
JOIN entries ON entries.student_id_fk = students.student_id 
JOIN subjects ON entries.subject_id_fk = subjects.subject_id 
GROUP BY students.first_name; 

Действительно единственное, что я не уверен в том, какой присоединиться использовать и где поставить его, или если таблицы должны быть перечислены в другом заказ. Я думаю, что это должно быть левое соединение, но я не уверен.

Помощь очень ценится!

+0

'ЛЕВЫЙ JOIN' должен работать. Разве это не работает с левым соединением? – Spidey

+0

Вы можете узнать о объединениях из [w3schools sql joins] (http://www.w3schools.com/sql/sql_join.asp) и этого [инфографика на SO] (http://stackoverflow.com/a/23653569/4879022) – Spidey

+0

Один вопрос: из вашего примера у вас есть только «NULL» в столбце 'subject_name' для ваших результатов, в приведенном ниже ответе предполагается, что вы не хотите, чтобы совпадения« NULL »находились в стороне« студентов »запроса. То, что вы хотите, чтобы все студенты независимо от соответствующих предметов. Если это неверно, и вы также хотите, чтобы все предметы, у которых не было никаких студенческих матчей, ответ на этот вопрос отвечает scaisEdge. Мой запрос не будет иметь нулей в списке учеников, только в предметах. Это означает, что вы получите всех учеников, но если у вас нет ученика, предмет не появится в списке. – gmiley

ответ

1

Вы должны использовать левое соединение, так как вы также хотите вернуть строку для ученика, у которой нет назначенного предмета. Кроме того, вы хотите отсортировать результат, а не группу. Таким образом, в конце концов, должно быть так:

SELECT students.first_name, subjects.subject_name 
FROM students 
LEFT JOIN entries ON entries.student_id_fk = students.student_id 
LEFT JOIN subjects ON entries.subject_id_fk = subjects.subject_id 
ORDER BY students.first_name; 
+0

Спасибо! Не могли бы вы объяснить мне, почему левое соединение используется как раз, а не только первое? – Dovahkiin

+1

После первого подключения к таблице записей вы получаете соединение таблиц студентов и записей (каждая строка будет иметь столбцы из обеих таблиц). Если вы будете использовать только JOIN, у вас не будет строк для студентов, которых нет в таблице записей (Alex). С LEFT JOIN у вас также будет Alex, и все столбцы для таблицы записей будут пустыми в этой строке. Второе соединение свяжет эти данные с таблицей предметов. Если вы будете использовать только JOIN, вы потеряете строку Alex, потому что ее нельзя присоединить к таблице предметов tiwh (столбец entries.subject_id_fk равен NULL, поэтому эта строка будет удалена). Надеюсь, это прояснит это. – abrcek

+0

Спасибо, это помогло. – Dovahkiin

0

Вы вероятно хотите LEFT OUTER JOIN:

select stu.first_name, sub.subject_name 
from students stu 
join entries e 
on stu.student_id = e.student_id_fk 
left outer join subjects sub 
on sub.subject_id = e.subject_id_fk 
order by stu.first_name; 

Я от моего компьютера с любым SQL установлен, так что это не проверялось, но должно дать вам то, что вы хотите.

  • Модифицированный мой ответ, чтобы заменить group by с order by как указывал другим. Это правильный способ сделать это, если только группа не является частью более крупного запроса, который вы, возможно, обрезали.
1

Я думаю, что это может быть запросом, но использовать порядок, а не группа (группа для агрегатной функции, как кол() или максимум())

SELECT students.first_name, subjects.subject_name 
FROM entries 
LEFT JOIN students ON entries.student_id_fk = students.student_id 
LEFT JOIN subjects ON entries.subject_id_fk = subjects.subject_id 
ORDER BY students.first_name; 
0

левый присоединиться студентов таблицу на остальных двух таблиц последовательно является правильный выбор, чтобы захватить все первокурсники имя.

Чтобы заказать имена , закажите по.

Я создал скрипт sql для лучшей визуализации того, как получить желаемый результат.

Вот ссылка: http://sqlfiddle.com/#!9/a1c850/7

Этот запрос

select students.student_name, subjects.subject_name 
from 
students 
left join entries on entries.student_id=students.student_id 
left join subjects on entries.subject_id=subjects.subject_id 
order by students.student_name; 
Смежные вопросы