2012-08-15 47 views
1

在SQL Server(2008)中,我想查找所有員工在一張表中具有3,4,5或4,5,6的技能。他們需要其中之一。例如,只有skillid = 4,不應該產生匹配。我如何構建這種類型的查詢?在單個表中查找多個ID匹配

一個實例表:

pkid, empid, skillid 
1  2  3 
2  2  4 
3  2  5 
4  5  6 

在上述例子中,EMPID = 2是對於該組3,4,5的匹配。 empid = 5不是。

回答

4

您將需要使用一個GROUP BYHAVING子句查詢:

select empid 
from t1 
where skillid in (3, 4, 5) 
    or skillid in (4, 5, 6) 
group by empid 
having count(distinct skillid) = 3 

SQL Fiddle with Demo

1

嘗試

select pkid, empid 
from your_table 
where skillid in (3,4,5) or skillid in (4,5,6) 
group by pkid, empid 
having count(distinct skillid) = 3 
1

前兩次的答案從無法區分受苦在(1,2,6)或(1,5,6)或(2,5,6)等中設置成員。結果必須僅顯示作爲ALL的成員的empid, 2,3或4,5,6。

嘗試:

 
    create table Table1 (pkid int constraint PK_Table1 primary key, empid int, skillid int) 

    insert into table1 values (1,2,1) 
    insert into table1 values (2,2,2) 
    insert into table1 values (3,2,3) 
    insert into table1 values (4,3,1) 

    SELECT empid 
    FROM (
     SELECT empid, sum(t.s1) as s1, sum(t.s2) as s2, sum(t.s3) as s3, sum(t.s4) as s4, sum(t.s5) as s5, sum(t.s6) as s6 
     FROM 
     (
      select empid, 1 s1, 0 s2, 0 s3, 0 s4, 0 s5, 0 s6 
      from table1 
      where skillid = 1 
      union all 
      select empid, 0, 1, 0, 0, 0, 0 
      from table1 
      where skillid = 2 
      union all 
      select empid, 0, 0, 1, 0, 0, 0 
      from table1 
      where skillid = 3 
      union all 
      select empid, 0, 0, 0, 1, 0, 0 
      from table1 
      where skillid = 4 
      union all 
      select empid, 0, 0, 0, 0, 1, 0 
      from table1 
      where skillid = 5 
      union all 
      select empid, 0, 0, 0, 0, 0, 1 
      from table1 
      where skillid = 6 
     ) t 
     GROUP BY t.empid 
    ) tt 
    WHERE (tt.s1 = 1 and tt.s2 = 1 and tt.s3 = 1) or (tt.s4 = 1 and tt.s5=1 and tt.s6=1) 
0

EMPID IN(3,4,5)是簡寫EMPID = 3或EMPID = 4或EMPID = 5,所以EMPID IN 3,4,5,OR IN EMPID( 4,5,6)與empid IN(3,4,5,6)相同。但是,我們需要避免用3,5,6或3,4,6來計算人數。你可以做這樣的事情:如果你願意,看看哪些EMPID的有兩套

SELECT empid, 345 AS skillset 
FROM your_table 
WHERE skillid IN (3,4,5) 
GROUP BY empid 
HAVING COUNT(DISTINCT skillid) = 3 
UNION ALL 
SELECT empid, 456 AS skillset 
FROM your_table 
WHERE skillid IN (4,5,6) 
GROUP BY empid 
HAVING COUNT(DISTINCT skillid) = 3 

你可以把一個SELECT解決這個問題,等

2

我你原來的問題的解讀是,要找到那些誰滿足以下任一條件的員工:

  • 他們有技能的IDS 3,4及5
  • 他們有技能ID 4和5和6

(或兩者)。如果這種情況下,你會想用相關子查詢做這樣的事情:

select * 
from employee e 
where ( exists (select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 3) 
     and exists (select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 4) 
     and exists (select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 5) 
    ) 
    OR ( exists (select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 4) 
     and exists (select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 5) 
     and exists (select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 6) 
    ) 

然而,由於你的兩個目標的技能集{3,4,5}和{4,5,6}有公共子集{4,5},我們可以簡化。重構,我們得到

select * 
from employee e 
where exists (select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 4  ) 
    and exists (select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 5  ) 
    and exists (select * from employee_skill es3 on es3.empid = e.empid and es3.skillid in (3 , 6)) 

另一種方法是使用left join

select * 
from employee e 
left join employee_skill es3 on es3.empid = e.empid and es3.skillid = 3 
left join employee_skill es4 on es4.empid = e.empid and es4.skillid = 4 
left join employee_skill es5 on es5.empid = e.empid and es5.skillid = 5 
left join employee_skill es6 on es6.empid = e.empid and es6.skillid = 6 
where es4.empid is not null 
    and es5.empid is not null 
    and ( es3.empid is not null 
     OR es6.empid is not null 
    ) 

使用left join後一種方法包含一個隱含的假設,某個員工/技能組合是在數據模型中是唯一的。如果情況並非如此,那麼這種方法將需要使用select distinct以免在結果集中出現重複行。