SQL – 从一个表中查找另一个表中不存在的logging

我有以下两个SQL表(在MySQL中):

Phone_book +----+------+--------------+ | id | name | phone_number | +----+------+--------------+ | 1 | John | 111111111111 | +----+------+--------------+ | 2 | Jane | 222222222222 | +----+------+--------------+ Call +----+------+--------------+ | id | date | phone_number | +----+------+--------------+ | 1 | 0945 | 111111111111 | +----+------+--------------+ | 2 | 0950 | 222222222222 | +----+------+--------------+ | 3 | 1045 | 333333333333 | +----+------+--------------+ 

如何找出哪些电话号码不在Phone_book ? 期望的输出将是:

 Call +----+------+--------------+ | id | date | phone_number | +----+------+--------------+ | 3 | 1045 | 333333333333 | +----+------+--------------+ 

任何帮助将不胜感激。

有几种不同的方法可以做到这一点,具有不同的效率,具体取决于查询优化器的性能以及两个表的相对大小:

这是最短的声明,如果你的电话簿很短,可能是最快的:

 SELECT * FROM Call WHERE phone_number NOT IN (SELECT phone_number FROM Phone_book) 

或者(感谢Alterlife )

 SELECT * FROM Call WHERE NOT EXISTS (SELECT * FROM Phone_book WHERE Phone_book.phone_number = Call.phone_number) 

或(感谢WOPR)

 SELECT * FROM Call LEFT OUTER JOIN Phone_Book ON (Call.phone_number = Phone_book.phone_number) WHERE Phone_book.phone_number IS NULL 

(如别人所说,忽略这一点,通常最好只select你想要的列,而不是' * ')

 SELECT Call.ID, Call.date, Call.phone_number FROM Call LEFT OUTER JOIN Phone_Book ON (Call.phone_number=Phone_book.phone_number) WHERE Phone_book.phone_number IS NULL 

应该删除子查询,使查询优化器发挥它的魔力。

另外,避免使用“SELECT *”,因为如果有人改变了底层的表或视图(而且效率低下),它可能会破坏你的代码。

下面的代码在处理大型数据集时比上面提供的答案要高效一些。

 SELECT * FROM Call WHERE NOT EXISTS (SELECT 'x' FROM Phone_book where Phone_book.phone_number = Call.phone_number) 

我认为

 SELECT CALL.* FROM CALL LEFT JOIN Phone_book ON CALL.id = Phone_book.id WHERE Phone_book.name IS NULL 
 SELECT DISTINCT Call.id FROM Call LEFT OUTER JOIN Phone_book USING (id) WHERE Phone_book.id IS NULL 

这将返回Phone_book表中缺less的额外ID。

 SELECT t1.ColumnID, CASE WHEN NOT EXISTS( SELECT t2.FieldText FROM Table t2 WHERE t2.ColumnID = t1.ColumnID) THEN t1.FieldText ELSE t2.FieldText END FieldText FROM Table1 t1, Table2 t2 
 SELECT name, phone_number FROM Call a WHERE a.phone_number NOT IN (SELECT b.phone_number FROM Phone_book b) 

或者,

 select id from call minus select id from phone_number