2013-06-29 79 views
0
employee_id | first_name | last_name 
-------------------------------------- 
00001   Tim   Smith 
00002   John   Doe 

employee_id | skill_id 
-------------------------------------- 
00001   1 
00001   2 
00002   1 
00002   3 

skill_id | name 
-------------------------------------- 
1   Java 
2   PHP 
3   MySQL 

我想與Java PHP技能選擇所有員工。與我上面的示例應該返回PostgreSQL的子查詢一一對多的關係搜索

employee_id | first_name | last_name 
-------------------------------------- 
00001   Tim   Smith 

我怎麼能在PostgrSQL中做到這一點?

回答

1

嘗試

SELECT e.employee_id, e.first_name, e.last_name 
    FROM employee e JOIN employee_skills es 
    ON es.employee_id = e.employee_id JOIN skills s 
    ON es.skill_id = s.skill_id 
WHERE s.name IN('PHP', 'Java') 
GROUP BY e.employee_id, e.first_name, e.last_name 
HAVING COUNT(DISTINCT s.skill_id) = 2 

如果在你的UI你已經知道skill_ids你可能會做,因爲你必須參考表,那麼你甚至不需要第二個連接

SELECT e.employee_id, e.first_name, e.last_name 
    FROM employee e JOIN employee_skills es 
    ON es.employee_id = e.employee_id 
WHERE es.skill_id IN(1, 2) 
GROUP BY e.employee_id, e.first_name, e.last_name 
HAVING COUNT(DISTINCT es.skill_id) = 2 

輸出:

 
| EMPLOYEE_ID | FIRST_NAME | LAST_NAME | 
---------------------------------------- 
|   1 |  Tim |  Smith | 

這裏是SQLFiddle demo

+0

可以使用類似'to_tsvector(s.name)@@ to_tsquery('PHP |')'的方式來代替這個'WHERE s.name IN('PHP','Java')' Java')' –

+0

@nelsonjuan可能。但爲什麼要這樣做呢?我建議選擇退出在查詢中使用技能名稱,並僅在UI中使用它們(如果這是應用程序中的可能性)。 – peterm

+0

@nelsonjuan如果答案有幫助,請考慮** [接受](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)**它。 – peterm