对于另一个表中字段的每个条件,选择不在另一个表中的行

时间:2012-03-27 10:36:04

标签: sql-server-2008

我有两张桌子:

具有列的代理:agentid,name

DocumentsRead with columns:agentid,document,dateread

我需要识别所有未读取文档读取表中每个文档的代理。因此,如果代理商拥有10条记录,而在DocumentsRead中,我有5条记录显示doc1已经被读取,4条记录显示doc2已被读取,我的预期结果应该有11条记录。 5显示未读取doc1的代理,6显示未读取doc2的代理。

我理解如何使用各种查询来识别DocumentsRead中不存在代理中的记录,但我无法弄清楚如何为DocumentsRead中列出的每个Document使其工作。

3 个答案:

答案 0 :(得分:1)

尝试此查询:

SELECT * 
FROM Agents, (SELECT DISTINCT document FROM DocumentsRead) docs 
WHERE NOT EXISTS (
    SELECT * 
    FROM DocumentsRead 
    WHERE agentid = Agents.agentid AND document = docs.document
)

答案 1 :(得分:1)

或者这个:

SELECT AG.AgentId, DOC.document
FROM Agents AG, 
(select document from DocumentsRead) DOC
except 
select DOC1.AgentId, DOC1.document from DocumentsRead DOC1

这个想法是:

a)如果每个代理都会读取每个文档,请获取表格:

SELECT AG.AgentId, DOC.document
FROM Agents AG, 
(select distinct document from DocumentsRead) DOC

b)获取代理商已阅读的文件:

select distinct DOC1.AgentId, DOC1.document from DocumentsRead DOC1

c)使用except从(a)中排除(b)(在这种情况下,不需要distinct

答案 2 :(得分:1)

或者这个(与@socha23's相同,只使用LEFT JOIN + WHERE IS NULL代替NOT EXISTS):

SELECT
  a.agentid,
  a.name,
  d.document
FROM Agents a
  CROSS JOIN (SELECT DISTINCT document FROM DocumentsRead) d
  LEFT JOIN DocumentsRead r ON a.agentid = r.agentid AND d.document = r.document
WHERE r.agentid IS NULL