2013-12-23 2 views
0

Чтобы упростить эту проблему, предположим, что это для школьной базы данных, и у нас есть 3 таблицы. В этой школе учащийся может участвовать в нескольких курсах, которые имеют многократные уроки, и мы храним в БД информацию о доступных курсах, уроках каждого курса и о том, какие курсы и уроки он изучает в настоящее время.Извлечение столбцов из реляционной базы данных

Таблица courses имеет 2 колонки, cs_id и cs_name. Таблица lessons имеет 3 столбца, ls_course, где хранится идентификатор курса, из которого урок: ls_number - последовательный номер, который идентифицирует урок в курсе и ls_name. В последней таблице students хранится идентификатор студента, st_id, идентификатор курса и текущий урок в этом курсе, st_course и st_lesson. Некоторые образцы данных:

courses 
+-------+----------+ 
| cs_id | cs_name | 
+-------+----------+ 
|  1 | Course A | 
|  2 | Course B | 
+-------+----------+ 

lessons 
+-----------+-----------+--------------+ 
| ls_course | ls_number | ls_name  | 
+-----------+-----------+--------------+ 
|   1 |   1 | Lesson One | 
|   1 |   2 | Lesson Two | 
|   1 |   3 | Lesson Three | 
|   2 |   1 | Lesson One | 
|   2 |   2 | Lesson Two | 
|   2 |   3 | Lesson Three | 
+-----------+-----------+--------------+ 

students 
+-------+-----------+-----------+ 
| st_id | st_course | st_lesson | 
+-------+-----------+-----------+ 
|  1 |   1 |   2 | 
|  2 |   1 |   3 | 
|  2 |   2 |   2 | 
+-------+-----------+-----------+ 

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

SELECT * FROM students WHERE st_id = 2; 

Это возвращает отфильтрованные строки, но я хотел бы получить курс и урок ID и имен для них. Чтобы получить столбец имени, конечно, я хотел бы сделать это:

SELECT s.*, c.cs_name 
FROM students s, courses c 
WHERE s.st_id = 2 AND s.st_course = c.cs_id 

Каких результатов в:

+-------+-----------+-----------+----------+ 
| st_id | st_course | st_lesson | cs_name | 
+-------+-----------+-----------+----------+ 
|  2 |   1 |   3 | Course A | 
|  2 |   2 |   2 | Course B | 
+-------+-----------+-----------+----------+ 

Дальний я могу получить это:

SELECT s.*, c.cs_name, l.ls_name 
FROM students s, courses c, lessons l 
WHERE 
    s.st_id = 2   AND 
    s.st_course = c.cs_id AND 
    s.st_lesson = l.ls_number 

Но как я могу извлечь идентификатор урока и глава, чтобы проверить соответствие в таблице уроков, возможно ли это вообще? В результате я хочу это:

+-------+-----------+-----------+----------+--------------+ 
| st_id | st_course | st_lesson | cs_name | ls_name  | 
+-------+-----------+-----------+----------+--------------+ 
|  2 |   1 |   3 | Course A | Lesson Three | 
|  2 |   2 |   2 | Course B | Lesson Two | 
+-------+-----------+-----------+----------+--------------+ 
+0

Что касается названий уроков, они не все одинаковы для каждого курса, как в этом примере. Это просто упрощение того, что я хочу сделать. – sidyll

ответ

2

Этот запрос является неправильным:

SELECT s.*, c.cs_name, l.ls_name 
    FROM students s, courses c, lessons l 
    WHERE 
     s.st_id = 2   AND 
     s.st_course = c.cs_id AND 
     s.st_lesson = l.ls_number 

Вы должны также соответствовать st_course к ls_course

SELECT s.*, c.cs_name, l.ls_name 
    FROM students s, courses c, lessons l 
    WHERE 
     s.st_id = 2   AND 
     s.st_course = c.cs_id AND 
     (s.st_lesson = l.ls_number AND st.st_course=l.ls_course) 

Я также рекомендую использовать текущий синтаксис JOIN, т.е.

SELECT s.*, c.cs_name, l.ls_name 
FROM students s 
JOIN courses c ON c.cs_id=s.st_course 
JOIN lessons l ON (s.st_lesson=l.ls_number AND st.st_course=l.ls_course) 
WHERE s.st_id = 2    
+0

Спасибо. Да, это было неправильно, я просто написал это как самый близкий запрос к тому, что я хочу. Твоя просто прекрасна. И спасибо за альтернативу «JOIN», о которой я и не подумал. – sidyll

+1

Я думаю, вы найдете синтаксис JOIN более читабельным. Рад, что он работает – Sparky

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