我有以下两个表(在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_number
不在Phone_book
中的人发出的?所需的输出将是:
Call
+----+------+--------------+
| id | date | phone_number |
+----+------+--------------+
| 3 | 1045 | 333333333333 |
+----+------+--------------+
9条答案
按热度按时间oprakyz71#
有几种不同的方法可以实现这一点,效率各不相同,具体取决于查询优化器的性能以及两个表的相对大小:
这是最短的语句,如果您的电话簿很短,这可能是最快的语句:
或者(由于Alterlife)
或(感谢WOPR)
(忽略这一点,正如其他人所说,通常最好只选择所需的列,而不是“
*
”)4uqofj5v2#
应该删除子查询,以便查询优化器发挥其作用。
另外,避免使用“SELECT *”,因为如果有人更改了基础表或视图,它可能会破坏您的代码(而且效率很低)。
jgovgodb3#
在处理较大的数据集时,下面的代码比上面给出的答案更有效。
3df52oht4#
这将返回Phone_book表中缺少的额外ID。
lndjwyie5#
我觉得
nkoocmlb6#
bzzcjhmw7#
qacovj5a8#
或者,
toe950279#
不要忘记检查索引!
如果你的表很大,你需要确保电话簿在
phone_number
字段上有一个索引。对于大表,数据库很可能选择扫描两个表。您应该创建包含
phone_number
的Phone_Book
和Call
索引。如果性能成为一个问题,请尝试这样的精简索引,其中只有电话号码:字段越少越好,因为它将不得不加载整个表。
如果您查看查询计划,它看起来会像这样,您可以确认新索引实际上正在使用。请注意,这是针对SQL Server的,但对于MySQL应该类似。
对于我展示的查询,除了扫描两个表中的每条记录,数据库几乎没有其他方法可以生成结果。