2012-06-27 3 views
0

У меня есть эти три таблицыSQL Сортировка 3 соединяемых таблиц

people 
============ 
id, name 

,

surveys 
============ 
id, org_id 

и

answer_sheets 
============ 
id, person_id, survey_id, answer, date_answered 
  • person_id и survey_id внешние ключи от people.id и surveys.id

Теперь, что я хотел сделать, это сортировать people в таких, чтобы основываясь на последних answer_sheets.date_answered (мы можем получить, что один surveys И people строка может иметь много answer_sheets) учитывая surveys.org_id

Скажем, например, у нас есть таблицы

people 
============ 
id name 
1 Person1 
2 Person2 
3 Person3 
4 Person4 
5 Person5 

surveys 
============ 
id org_id 
1 1 
2 1 
3 2 
4 2 


answer_sheets 
============= 
id person_id survey_id answer date_answered 
1 1   1   string JUN 13 
2 2   1   string JUN 15 
3 3   2   string JUN 17 
4 2   2   string JUN 18 
5 1   2   string JUN 19 
6 3   3   string JUN 20 
7 2   3   string JUN 25 
8 4   3   string JUN 27 
9 4   4   string JUN 27 

и я хотел заказать people в ASC порядке, основанном на people Роу последних answer_sheets.date_answered в обзорах, имеющих org_id = 1

выход будет

============= 
id name  last_date_answered 
4 Person4 NIL 
5 Person5 NIL 
3 Person3 JUN 17 
2 Person2 JUN 18 
1 Person1 JUN 19 

Вы можете заметить, что people с id s 4 и 5 не в surveys в answer_sheet с org_id = 1 и все же они должны быть включены в список. Вопрос: Для чего нужен соответствующий SQL-запрос? Благодарю.

+1

Это домашнее задание? – tsells

ответ

1

Этот запрос по-прежнему действует, однако другие ответы лучше. Fiddle остается в силе, хотя

http://sqlfiddle.com/#!2/3aac2/1/0

Вот про лучшее, что я мог бы сделать за это время ночи. Да, это уродливое (очень, очень уродливое), но оно дает желаемый результат. Мне очень не нравится, что я должен был использовать союз и вход, но поздно ночью, поэтому я, вероятно, что-то пропустил. В этой записке, если это/является/домашним заданием, вы, вероятно, захотите остаться далеко от этого решения. Если это не так, есть скрипку в нижней части, чтобы помочь другим людям помочь вам

SELECT people.id, 
    people.name, 
    MAX(date_answered) AS date_answered 
FROM people 
LEFT OUTER JOIN answer_sheets ON answer_sheets.person_id = people.id 
INNER JOIN surveys ON surveys.id = answer_sheets.survey_id 
GROUP BY people.id, 
    surveys.org_id HAVING surveys.org_id = 1 
UNION 
SELECT ALL people.id, 
     people.name, 
     NULL AS date_answered 
FROM people 
WHERE people.id NOT IN 
    (SELECT person_id 
    FROM answer_sheets 
    INNER JOIN surveys ON answer_sheets.survey_id = surveys.id 
    WHERE surveys.org_id = 1) 
ORDER BY date_answered 

Используйте один из приведенных ниже решений, слева на присоединение подзапроса лучше. Fiddle остается в силе, хотя

Если кто-то хочет, чтобы улучшить это, не стесняйтесь использовать эту скрипку: http://sqlfiddle.com/#!2/3aac2/1/0

1

Этот запрос проще:

SELECT 
    p.id, 
    p.name, 
    t.last_date_answered 
FROM people p 
LEFT JOIN (
    SELECT 
     a.person_id, 
     MAX(a.date_answered) as last_date_answered 
    FROM answer_sheets a 
    INNER JOIN surveys s ON a.survey_id = s.id 
    WHERE s.org_id = 1 
    GROUP BY a.person_id) t ON p.id = t.person_id 
ORDER BY t.last_date_answered; 

UNION является мощный тоже, но здесь LEFT JOIN менее подробный.

0
SELECT 
    p.id, p.name, MAX(a.date_answered) 
FROM 
    people p 
LEFT JOIN 
    (SELECT * FROM 
    answer_sheets a 
    INNER JOIN 
    surveys S ON a.survey_id = s.id 
    WHERE S.orgid = 1) a 
ON 
    p.id = a.personID 
GROUP BY 
    p.id, p.name 
ORDER BY MAX(date_answered) ASC 

Это наиболее оптимизированный ответ. Кредиты моей подруге Шейле Рут Фаусто.

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