在单个表中查找多个ID匹配项

时间:2012-08-15 21:05:23

标签: sql sql-server tsql

在SQL Server(2008)中,我想在单个表中找到技能为3,4,5或4,5,6的所有员工。他们需要拥有其中一组。例如,只要拥有skillid = 4,就不应该产生匹配。如何构建此类查询?

示例表:

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

在上面的例子中,empid = 2是集合3,4,5的匹配。 empid = 5不是。

5 个答案:

答案 0 :(得分: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 :(得分:2)

我对原始问题的解读是,您希望找到符合以下任一条件的员工:

  • 他们有技能ID 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,以免在结果集中出现重复的行。

答案 2 :(得分: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

答案 3 :(得分:1)

以前的答案都无法区分(1,2,6)或(1,5,6)或(2,5,6)等的集合成员资格。结果必须只显示这是1,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)

答案 4 :(得分:0)

empid IN(3,4,5)是empid = 3或empid = 4或empid = 5的简写,所以empid IN 3,4,5,或者empid IN(4,5,6)是相同的在IN(3,4,5,6)中。但是,我们需要避免用3,5,6或3,4,6计算人数。你可以这样做:

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

如果你想看哪个empid有这两个集合,你可以在这周围放一个SELECT。