SQL如何在几个表中查找未使用的密钥

时间:2017-09-18 16:10:17

标签: sql sql-server

SQL,一个表(thesau),其中的术语可能会或可能不会在其他几个表中使用。其他表格指向thes中的id。我想找出哪些条款未被使用,即哪些条款未被任何其他表格引用。简化:

table: thesau
id term
1  painting
2  sari
4  oil
5  silk
8  gouache

table: object_type
id
1   (-> painting)
7   (-> ... )

table: material_type:
id
2   (-> silk)
4   (-> oil)

在集合中,object_type 1指的是thesau 1 =绘画,依此类推。现在,我可以在一个表中找到未使用的sau项,如下所示:

select distinct thesau.id, thesau.term from thesau_term 
  where thesau_term.id not in 
  (select object_type.id from object_type)

这很有效。我想在一个查询中将相同的查询扩展到其他表,如果可能的话。在伪代码中:

select distinct id, term from thesau_term 
  where thesau_term.id not in 
  ((select object_type.id from object_type) or
   (select material_type.id from material_type))

这不起作用。我错过了什么?

2 个答案:

答案 0 :(得分:2)

您当前的查询会列出至少在另一个表中未使用的字词。如果您使用AND代替OR,则您的查询会列出未在其他任何表格中使用的字词:

select distinct id, term from thesau_term 
  where thesau_term.id not in 
  ((select object_type.id from object_type) AND -- <<== HERE
   (select material_type.id from material_type))

您可以使用NOT EXISTS

进一步简化查询
SELECT id, term
FROM thesau_term t
WHERE
    NOT EXISTS (SELECT * FROM object_type ot WHERE ot.id=t.id)
AND NOT EXISTS (SELECT * FROM material_type mt WHERE mt.id=t.id)

或使用外部联接

SELECT DISTINCT t.id, t.term
FROM thesau_term t
LEFT OUTER JOIN object_type ot ON ot.id=t.id
LEFT OUTER JOIN material_type mt ON mt.id=t.id
WHERE ot.id IS NULL and mt.id IS NULL

答案 1 :(得分:1)

您不需要使用join,您可以执行您在第一次查询中所做的操作,只需更改where子句即可。 not exists将是最永久的,但这样的事情会起作用:

SELECT DISTINCT
       id,
       term
FROM thesau_term
WHERE thesau_term.id NOT IN
(
    SELECT object_type.id
    FROM object_type
)
      OR thesau_term.id NOT IN
(
    SELECT material_type.id
    FROM material_type
);