2015-03-25 3 views
1

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

Vocab стол:

CREATE TABLE `se_vocab` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `vocab_word` VARCHAR(255) NOT NULL, 
    `vocab_audio` INT(10) NULL DEFAULT '0', 
    `vocab_image` INT(10) NULL DEFAULT '0', 
    PRIMARY KEY (`id`) 
) 

видео таблица:

CREATE TABLE `se_video` (
    `id` INT(10) NOT NULL AUTO_INCREMENT, 
    `video_name` VARCHAR(255) NOT NULL, 
    `video_description` MEDIUMTEXT NOT NULL, 
    `video_file_name` VARCHAR(50) NULL DEFAULT NULL, 
    `video_url` VARCHAR(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) 

викторин стол:

CREATE TABLE `se_quizzes` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `quiz_name` VARCHAR(80) NOT NULL, 
    `quiz_description` TINYTEXT NULL, 
    PRIMARY KEY (`id`) 
) 

объектов урока (содержат внешние ключи предыдущих таблиц)

CREATE TABLE `se_lesson_org` (
    `id` INT(10) NOT NULL AUTO_INCREMENT, 
    `lesson_id` INT(10) NOT NULL, 
    `section_object_type` ENUM('video','vocabulary','quiz') NOT NULL, 
    `section_object_id` INT(10) NOT NULL, 
    PRIMARY KEY (`id`) 
) 

Я пытаюсь создать запрос, который возвращает все записи из lesson_objects, но и включает в себя данные в столбцах для данного типа в этой записи (словарный запас и т.д.)

Например: enter image description here

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

Мои попытки очень плохо, но вот один для руководства:

SELECT 
    lo.id, lo.section_object_type, lo.section_object_id, 
    vo.id, vo.vocab_text, vo.vocab_image, vo.vocab_audio 
    vi.id, vi.video_name, vi.video_url, 
    q.id, q.quiz_name 
    FROM se_lesson_org lo, se_vocab vo, se_video vi, se_quizzes q 
    WHERE lo.section_object_id = vo.id 
    OR lo.section_object_id = vi.id 
    OR lo.section_object_id = q.id 

Любая помощь/комментарии будут оценены. Благодарю.

+0

Показать образец данных или создать sqlfiddle – Jens

+1

Пожалуйста, напишите ожидаемый формат результата. –

+0

MySQL или SQL Server? Не помещайте продукты, которые не задействованы! – jarlh

ответ

2

Используйте LEFT JOIN, чтобы возвратить все строки с se_lesson_org. Кроме того, добавить условие JOIN в соответствии с конкретной section_object_type

SELECT 
    lo.*, 
    vo.*, 
    vi.*, 
    q.* 
FROM se_lesson_org lo 
LEFT JOIN se_vocab vo 
    ON vo.id = lo.section_object_id 
    AND lo.section_object_type = 'vocabulary' 
LEFT JOIN se_video vi 
    ON vi.id = lo.section_object_id 
    AND lo.section_object_type = 'video' 
LEFT JOIN se_quizzes q 
    ON q.id = lo.section_object_id 
    AND lo.section_object_type = 'quiz' 

Примечание: Не используйте старый стиль JOIN синтаксис. Прочитайте это article от Aaron Bertrand.

+0

Удивительный материал. Работает отлично. Я посмотрю на эту статью. Благодаря! – markbratanov

+0

Без проблем, рад, что я мог бы помочь. –

+1

Хорошая статья, @wewesthemenace. Что он имеет в виду, когда говорит о '* =, = *'? Наверное, тупой вопрос, но я не вижу его в запросе, на который он ссылается ... –

1

Похоже, что вы ищете LEFT JOIN на каждой из этих таблиц. Таким образом, если внешний ключ действителен, вы покажете значения, и если он недействителен, вы просто получите NULL для соответствующих столбцов.

SELECT 
    lo.id, lo.section_object_type, lo.section_object_id, 
    vo.id, vo.vocab_text, vo.vocab_image, vo.vocab_audio 
    vi.id, vi.video_name, vi.video_url, 
    q.id, q.quiz_name 
    FROM se_lesson_org lo 
    LEFT JOIN se_vocab vo ON vo.id = lo.section_object_id 
     AND lo.section_object_type = 'vocabulary' 
    LEFT JOIN se_video vi ON vi.id = lo.section_object_id 
     AND lo.section_object_type = 'video' 
    LEFT JOIN se_quizzes q ON q.id = lo.section_object_id 
     AND lo.section_object_type = 'quiz' 

Обратите также внимание, как этот синтаксис дает понять, как каждая таблица соединена в остальной части запроса, вместо того, весь беспорядок условий в ИНЕКЕ в конце.

+0

Отлично работает, и спасибо за объяснение. Я думаю, именно поэтому я беру класс SQL в этом семестре. – markbratanov

Смежные вопросы