ЛЕВЫЙ НАРУЖНЫЙ ПРИСОЕДИНЯЙТЕСЬ С УСЛОВИЯМИ (где, по порядку)? - PullRequest
5 голосов
/ 10 августа 2011

Я работаю над проектом Rails3 с базами данных MySql (локальная) и Postgresql (Heroku).
Мне нужно поставить условия на левое внешнее соединение, но я не знаю, как.

У меня есть 2 таблицы TRAININGS и TRAINING_HISTORIES.
Я хочу получить все записи TRAININGS и добавить последнюю действительную (или законченную) связанную запись TRAINING_HISTORIES.

Таблица ТРЕНИНГОВ

id  name  order_by
5   A     1  
6   B     2  
7   C     3

таблица TRAINING_HISTORIES

id  training_id finished_at score
43  5           2011-06-06  10
44  5           null        null
45  6           2011-07-07  11
46  6           2011-08-08  14
47  6           null        null
48  6           2011-09-09  18
49  6           null        null
50  7           null        null
51  7           2011-10-10  19

Вот мой SQL-запрос:

SELECT tc.id, tc.name, tc.order, 
th.id as history_id, th.finished_at, th.score
FROM trainings tc
LEFT OUTER JOIN training_histories th ON th.training_id = tc.id
WHERE tc.id > 4
AND tc.id < 8
GROUP BY tc.id
ORDER BY tc.order_by ASC, tc.id ASC

РЕЗУЛЬТАТЫ, КОТОРЫЕ Я ИМЕЮ:

id  name  order history_id  finished_at score
5   A     1     43          2011-06-06  10
6   B     2     45          2011-07-07  11
7   C     3     50          null        null
  • Запрос извлекает первую историю обучения для каждого соединения

РЕЗУЛЬТАТЫ, КОТОРЫЕ Я НУЖЕН:

id  name  order history_id  finished_at score
5   A     1     43          2011-06-06  10
6   B     2     48          2011-09-09  18
7   C     3     51          2011-10-10  19
  • В этом сценарии: последняя законченная история обучения, которая была найдена ...

Любые предложения действительно приветствуются!

Спасибо

РЕДАКТИРОВАТЬ: Если кто-то может ответить на части Rails, это тоже может быть здорово; -)
Как преобразовать SQL-запрос в Rails-запрос Active Record?

Ответы [ 3 ]

8 голосов
/ 10 августа 2011

Попробуйте этот запрос, он даст вам каждое обучение и самую последнюю историю обучения для каждого:

SELECT tc.id, tc.name, tc.order, 
th.id as history_id, th.finished_at, th.score
FROM trainings tc
LEFT OUTER JOIN training_histories th ON th.training_id = tc.id 
    and th.id =
    (SELECT th1.id from training_histories th1 where th1.training_id = tc.id
     and th1.finished_at is not null
     order by th1.finished_at desc limit 1)
WHERE tc.id > 4
AND tc.id < 8
GROUP BY tc.id
ORDER BY tc.order_by ASC, tc.id ASC
1 голос
/ 10 августа 2011

Я уверен, что вы можете сделать

SELECT tc.id, tc.name, tc.order, 
th.id as history_id, th.finished_at, th.score
FROM trainings tc
LEFT OUTER JOIN (SELECT id, training_id, MAX(finished_at) as finished_at, score 
    FROM training_histories GROUP BY training_id) th ON th.training_id = tc.id
WHERE tc.id > 4
AND tc.id < 8
GROUP BY tc.id
ORDER BY tc.order_by ASC, tc.id ASC
0 голосов
/ 10 августа 2011

Также в состоянии where проверьте finished_at not null и добавьте Order by finished_at DESC

SELECT tc.id, tc.name, tc.order, 
th.id as history_id, th.finished_at, th.score
FROM trainings tc
LEFT OUTER JOIN training_histories th ON th.training_id = tc.id
WHERE tc.id > 4
AND tc.id < 8
AND th.finished_at IS NOT NULL
GROUP BY tc.id
ORDER BY tc.order_by ASC, tc.id ASC, th.finished_at DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...