TSQL获取表中不存在的记录

时间:2014-08-14 14:06:59

标签: sql sql-server inner-join exists not-exists

我有一张表格,其中包含员工的数据和他们所采用的调查问卷的结果。调查问卷有3个问题,但并非所有问题都必须回答。我试图找出员工没有回答的问题。

EmployeeData:

EmployeeID | Question | Answer
-------------------------------
12345      | 1        | 100
-------------------------------
12345      | 2        | 85
-------------------------------
11111      | 1        | 100
-------------------------------
11111      | 2        | 90
-------------------------------
11111      | 3        | 25
-------------------------------

如果使用上表,我正在尝试编写一个返回的查询:

EmployeeID | Question
----------------------
12345      | 3 
----------------------

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:2)

执行此操作的方法是为所有员工创建所有问题的列表,然后删除已经回答的问题。

您可以使用子查询,cross joinleft outer join执行此操作:

select e.*, q.*
from (select distinct employeeid from employeedata) e cross join
     (select distinct question from employeedata) q left join
     employeedata ed
     on ed.employeeid = e.employeeid and ed.question = q.question
where ed.employeeid is null;

答案 1 :(得分:2)

首先,您需要一份员工清单。如果员工表存在,则更好的来源是。如果员工没有填写调查怎么办?

但根据您的要求,我们会使用表格中的员工。

SELECT DISTINCT EmployeeID FROM EmployeeData

现在我们需要添加可能的问题。为此,您可以使用临时表,但我们只使用硬编码的SQL。

SELECT 1 AS Question UNION ALL SELECT 2 UNION ALL SELECT 3

现在我们加入他们没有加入条件。这将生成一个包含EmployeeID的表和3个问题中的每一个。现在我们可以从这个表中选择所有可能性,并找到EmployeeData中不存在的那些。为此,我们要做一堆表值子查询。

SELECT EQ.EmployeeID, EQ.Question
FROM (SELECT E.EmployeeID, Q.Question
      FROM (SELECT DISTINCT EmployeeID FROM EmployeeData) AS E
           INNER JOIN (SELECT 1 AS Question UNION ALL SELECT 2 UNION ALL SELECT 3) AS Q ON (1=1) ) AS EQ
WHERE NOT EXISTS (SELECT Answer FROM EmployeeData WHERE EmployeeData.EmployeeID = EQ.EmployeeID AND EmployeeData.Question = EQ.Question)

您还可以将外部联接留在员工数据上并检查空值而不是使用not exists子句。

SELECT EQ.EmployeeID, EQ.Question
FROM (SELECT E.EmployeeID, Q.Question
      FROM (SELECT DISTINCT EmployeeID FROM EmployeeData) AS E
           INNER JOIN (SELECT 1 AS Question UNION ALL SELECT 2 UNION ALL SELECT 3) AS Q ON (1=1) ) AS EQ
     LEFT OUTER JOIN EmployeeData ON (EmployeeData.EmployeeID = EQ.EmployeeID AND EmployeeData.Question = EQ.Question)
WHERE EmployeeData.Answer IS NULL

答案 2 :(得分:0)

这样的事也应该有效。

select distinct question into #temp from EmployeeData

select ed.employeeid, a.question
from EmployeeData ed
cross join #temp a
where not exist (select 1 from EmployeeData ed1 where ed1.employeeid=ed.employeeid and ed1.question=a.question)