2012-06-27 32 views
0

我有這三個表SQL 3級聯接表排序

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

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

answer_sheets 
============ 
id, person_id, survey_id, answer, date_answered 
  • person_idsurvey_idpeople.id和外鍵現在

,我想要做的是,以排序在這樣people使其基於最新answer_sheets.date_answered給出的surveys.org_id

(我們可以得出一個surveyspeople行可以有很多answer_sheets)比方說,我們有表

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 

,我想根據在ASC以訂購行中有org_id = 1

調查的最新answer_sheets.date_answered輸出將

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

你可以觀察到peopleid第4和第5沒有在surveysanswer_sheetorg_id = 1,但他們應列入清單。 問題:什麼是適當的SQL查詢?謝謝。

+1

這功課嗎? – tsells

回答

1

該查詢仍然有效,但其他答案更好。 小提琴仍然是有效的,雖然

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 
以下解決方案

使用一個,左側的接合部上的子查詢更好。小提琴仍然是有效的,雖然

如果有人想在這個改進,隨意使用此琴: 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 

這是最優化的答案。感謝我的朋友希拉魯斯福斯托。