MySQL join, запрос на возврат всех заголовков глав и, где возможно, оценка пользователя - PullRequest
2 голосов
/ 07 мая 2011

У меня есть такие таблицы:

[users] [chapters] [exam_scores]
- id    - title    - fk_chapter
                   - fk_user
                   - grade

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

select chapters.title as Title, exam_scores.grade as Results
from users, exam_scores left join chapters
on chapters.id = exam_scores.fk_chapter
where exam_scores.fk_user = users.id and users.id = 15;

Этот возвращает записи, если есть доступная оценка, но не остальные главы.

Ответы [ 5 ]

0 голосов
/ 07 мая 2011

Попробуйте:

SELECT 
    chp. * , scr. * , usr. *
FROM 
    chapter AS chp
LEFT JOIN 
     scores AS scr ON scr.chapter_id = chp.id
LEFT JOIN 
     users AS usr ON usr.id = scr.user_id WHERE usr.id =15
0 голосов
/ 07 мая 2011

Поскольку вы хотите получить список всех глав, независимо от того, есть ли оценка пользователя для главы. Из-за этого вы хотите выбрать из таблицы глав. Затем, поскольку вы хотите получить результат для каждой главы, вам нужно СЛЕДУЕТ ПРИСОЕДИНИТЬСЯ к таблице exam_scores, чтобы получить записи для строк, которые имеют оценки, и записи для оценок, которые не имеют. При использовании естественного соединения (JOIN или FROM table, table2, table3) возвращаются только те записи, для которых совпадают левые и правые значения.

Итак, ваш запрос должен выглядеть так:

SELECT c.title Title, s.grade Results
FROM chapters c
LEFT JOIN exam_scores s ON s.fk_chapter = c.id
WHERE (s.fk_user = 15 OR s.fk_user IS NULL)

Обратите внимание, вам не нужно даже включать сюда таблицу users, так как вы не получаете никакой информации для нее. Ваш запрос присоединяется к таблице пользователей и затем выполняет предложение WHERE для ее ключа id. Это не требуется, если только вы не получаете данные из таблицы пользователей. Если вам действительно нужны данные из таблицы пользователя, вы ЛЕВЫЕ ПОДКЛЮЧАЕТЕ их к таблице exam_scores следующим образом:

SELECT c.title Title, s.grade Results, u.*
FROM chapters c
LEFT JOIN exam_scores s ON s.fk_chapter = c.id
LEFT JOIN users u ON u.id = s.fk_user
WHERE (s.fk_user = 15 OR s.fk_user IS NULL)

Надеюсь, что это поможет и пролит некоторый свет на то, как вы должны лучше структурировать свои запросы и присоединяться в будущем.

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

Когда вы объединяете 2 таблицы вместе, они объединяются идентификатором пользователя. Это нормально, потому что, когда идентификатор пользователя не отображается в таблице глав, вы получаете значение NULL для идентификатора пользователя и оценки. Однако, поскольку в нашем предложении WHERE мы фильтруем пользователя с идентификатором 15, он отфильтровывает все значения NULL для пользовательских столбцов. Итак, чтобы исправить это, вы добавляете оператор OR в ваше предложение WHERE, в котором говорится, что идентификатор пользователя NULL в порядке.

0 голосов
/ 07 мая 2011

Да, осталось присоединиться дважды:

select 
    chapters.title as Title
    , exam_scores.grade as Results
from 
    users 
    left outer join exam_scores 
        on (users.id = exam_scores.fk_user)
    left outer join chapters 
        on (exam_scores.fk_chapter = chapters.id)
where
    users.id = 15
;
0 голосов
/ 07 мая 2011
SELECT chapters.title AS Title, user_scores.grade AS Results
FROM chapters
LEFT JOIN  
       ( SELECT fk_chapter, grade FROM exam_scores
         JOIN users ON exam_scores.fk_user = users.id
         WHERE users.id = 15 ) user_scores 
ON chapters.id = user_scores.fk_chapter
0 голосов
/ 07 мая 2011

Вам нужно будет LEFT JOIN дважды, чтобы выполнить это.Кроме того, я бы также рекомендовал избегать синтаксиса соединения «старого стиля» (FROM table1, table2, table3 ...), поскольку эти типы объединения слишком запутаны.

select chapters.title as Title,
       exam_scores.grade as Results
from users
left join exam_scores
on exam_scores.fk_user = users.id
left join chapters
on chapters.id = exam_scores.fk_chapter
where users.id = 15;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...