SQL Server将Table1中的所有行与Table2中的所有行进行匹配

时间:2014-05-30 03:26:21

标签: sql sql-server database

有人请帮我解决这个问题, 我有2张桌子

员工

EmployeeID   LanguageID
1            1
1            2
1            3
2            1
2            3
3            1
3            2
4            1
4            2
4            3

任务

TaskID   LanguageID   LangaugeRequired
1        1            1
1        2            0
2        1            1
2        2            1
2        3            1
3        2            0
3        3            1

LangaugeID连接到表langauge(此表仅用于解释)

   LangaugeID   LanguageName
   1            English
   2            French
   3            Italian

是否有可能进行查询,让员工可以说出每项任务所需的所有语言?

例如:

  1. 任务ID 1仅需要LanguageID = 1,因此结果应为EmployeeID 1,2,3,4
  2. 任务ID 2需要所有3种语言,因此结果应为EmployeeID 1,4
  3. 任务ID 3仅需要LanguageID = 3,因此结果应为EmployeeID 1,2,4

3 个答案:

答案 0 :(得分:5)

这是另一种变体:

select t1.taskid, t2.employeeid from
(
    select a.taskid, count(distinct a.languageid) as lang_cnt
    from
    task as a
    where a.LangaugeRequired=1
    group by a.taskid
) as t1
left outer join
(
    select a.taskid, b.employeeid, count(distinct b.languageid) as lang_cnt
    from
    task as a
    inner join
    employee as b
    on (a.LangaugeRequired=1 and a.languageid=b.languageid)
    group by a.taskid, b.employeeid
) as t2
on (t1.taskid=t2.taskid and t1.lang_cnt=t2.lang_cnt)
###
here you can insert where statement, like:
where t1.taskid=1 and t2.employeeid=1
if such query returns row - this employee can work with this task, if no rows - no
###
order by t1.taskid, t2.employeeid

如您所见,此查询创建两个临时表,然后将它们连接起来。

第一个表(t1)计算每个任务需要多少种语言

第二个表(t2)查找所有具有任务所需语言的人员,按任务/员工分组以查找该员工可以使用的语言数

主查询执行LEFT JOIN,因为可能存在没有员工可以执行任务的情况

这是输出:

task    employee
1       1
1       2
1       3
1       4
2       1
2       4
3       1
3       2
3       4

更新:更简单但不太正确的变体,因为它不会在没有可能的员工的情况下返回任务

select a.taskid, b.employeeid, count(distinct b.languageid) as lang_cnt
from
task as a
inner join
employee as b
on (a.LangaugeRequired=1 and a.languageid=b.languageid)
group by a.taskid, b.employeeid
having count(distinct b.languageid) = (select count(distinct c.languageid) from task as c where c.LangaugeRequired=1 and c.taskid=a.taskid)

答案 1 :(得分:1)

使用NOT EXISTS

的另一个版本

检索缺少语言不存在的所有任务 - 员工组合

SELECT t1.EmployeeId, t2.TaskId
FROM (
    SELECT DISTINCT EmployeeID
    FROM Employee
) t1 , (
    SELECT DISTINCT TaskID
    FROM Task
) t2
WHERE NOT EXISTS (   
    SELECT 1 FROM Task t
    LEFT JOIN Employee e 
        ON e.EmployeeID = t1.EmployeeID
        AND e.LanguageID = t.LanguageID
    WHERE t.TaskID = t2.TaskID
    AND LanguageRequired = 1
    AND e.EmployeeID IS NULL
)

http://www.sqlfiddle.com/#!6/e3c78/1

答案 2 :(得分:-3)

您可以使用Join逻辑来获得结果,例如:

SELECT a.EmployeeID FROM Employee a, Task b WHERE b.LanguageRequired == a.LanguageID;