Как включить отфильтрованные строки строк из двух других таблиц в запрос третьей? - PullRequest
1 голос
/ 22 января 2009

У меня есть база данных MySql с тремя таблицами, которые мне нужно объединить в запросе: расписание, регистрация и список ожидания. Они внедряют базовую систему регистрации в классах.

Расписание содержит запланированные занятия. Когда пользователь регистрируется в классе, его идентификатор учетной записи пользователя и идентификатор запланированного класса сохраняются в зарегистрированном. Если класс заполнен, он хранится в списке ожидания. Все три таблицы имеют общий столбец scheduleId, который идентифицирует каждый класс.

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

Предварительный запрос, который я придумал для достижения этой цели:

select s.id, s.classDate, s.instructor, COUNT(e.id) as enrolled
from schedule as s
left outer join enrolled as e
on s.id = e.scheduleId
group by s.id

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

Ответы [ 3 ]

4 голосов
/ 22 января 2009

Использовать вложенные запросы SELECT. Предположим немного о вашей схеме, как примерно так (может не работать на некоторых разновидностях SQL):

select s.id, s.classDate, s.instructor, 
       (select COUNT(e.id) from enrolled e where e.scheduleId = s.id) as enrolled,
       (select COUNT(w.id) from waitlist w where w.scheduleId = s.id) as waiting
from schedule as s
group by s.id
3 голосов
/ 22 января 2009

Я бы сделал это с другим левым соединением и двумя встроенными счетчиками (различается)

select s.id, s.classDate, s.instructor ,
count(distinct e.id) as enrolled,
count(distinct w.id) as waiting
from schedule as s
left outer join enrolled as e
on s.id = e.scheduleID
left outer join waitlist as w
on s.id = w.scheduleID
group by s.id

Когда я запускал этот подход по сравнению с подзапросами, он выполнялся примерно вдвое быстрее, но я смотрю на довольно небольшой набор результатов.

0 голосов
/ 22 января 2009

Два быстрых способа:

1- Используйте COUNT(DISTINCT e.id), COUNT(DISTINCT w.id), чтобы получить количество уникальных экземпляров в каждой таблице, затем присоединитесь к обоим. Это возможно ужасно неэффективно.

2 - использовать подзапросы в предложении FROM (работает только в MySQL 5.0 и более поздних версиях):

SELECT s.id, s.classDate, s.instructor, tmpE.c AS enrolled, tmpW.c AS waiting
FROM
  schedule AS s,
  ( SELECT scheduleID, COUNT(*) AS c FROM enrolled GROUP BY scheduleID ) AS tmpE,
  ( SELECT scheduleID, COUNT(*) AS c FROM waiting GROUP BY scheduleID ) AS tmpW
WHERE
    s.id = e.scheduleID
    AND s.id = w.scheduleID
GROUP BY s.id

Возможно, я пропустил левое соединение там.

...