Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 从一个不包含';不存在于另一个世界_Sql_Mysql - Fatal编程技术网

Sql 从一个不包含';不存在于另一个世界

Sql 从一个不包含';不存在于另一个世界,sql,mysql,Sql,Mysql,我有以下两个表(在MySQL中): 我如何找出哪些电话是由电话号码不在电话簿中的人打的?所需的输出将是: Call +----+------+--------------+ | id | date | phone_number | +----+------+--------------+ | 3 | 1045 | 333333333333 | +----+------+--------------+ 根据查询优化程序的性能以及两个表的相对大小,有几种不同的方法可以实现这一点,但效率不同: 这

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

我如何找出哪些电话是由
电话号码不在
电话簿中的人打的?所需的输出将是:

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

根据查询优化程序的性能以及两个表的相对大小,有几种不同的方法可以实现这一点,但效率不同:

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

SELECT  *
FROM    Call
WHERE   phone_number NOT IN (SELECT phone_number FROM Phone_book)
或者(感谢)

或者(感谢WOPR)


(忽略这一点,正如其他人所说,通常最好只选择所需的列,而不是“
*
”)

在处理较大的数据集时,下面的代码将比上面给出的答案更有效率

SELECT * FROM Call WHERE 
NOT EXISTS (SELECT 'x' FROM Phone_book where 
Phone_book.phone_number = Call.phone_number)
应该删除子查询,让查询优化程序发挥其魔力

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

我认为

SELECT CALL.* FROM CALL LEFT JOIN Phone_book ON 
CALL.id = Phone_book.id WHERE Phone_book.name IS NULL
这将返回您的电话簿表中缺少的额外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 id from call
minus
select id from phone_number
别忘了检查你的索引! 如果您的表很大,您需要确保电话簿在
phone\u number
字段上有索引。对于大型表,数据库最有可能选择扫描这两个表

SELECT *
FROM   Call
WHERE  NOT EXISTS
  (SELECT *
   FROM   Phone_book
   WHERE  Phone_book.phone_number = Call.phone_number)
ALTER TABLE [dbo].Phone_Book ADD CONSTRAINT [IX_Unique_PhoneNumber] UNIQUE NONCLUSTERED 
(
    Phone_Number
)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = ON) ON [PRIMARY]
GO
您应该创建包含
电话号码的
电话簿
通话
索引。如果性能成为一个问题,请尝试这样的精简索引,只需电话号码:

字段越少越好,因为它必须完全加载它。两个表都需要索引

SELECT *
FROM   Call
WHERE  NOT EXISTS
  (SELECT *
   FROM   Phone_book
   WHERE  Phone_book.phone_number = Call.phone_number)
ALTER TABLE [dbo].Phone_Book ADD CONSTRAINT [IX_Unique_PhoneNumber] UNIQUE NONCLUSTERED 
(
    Phone_Number
)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = ON) ON [PRIMARY]
GO
如果您查看查询计划,它将是这样的,您可以确认您的新索引实际上正在使用。注意这是针对SQL Server的,但对于MySQL应该类似

通过查询,我发现数据库除了扫描两个表中的每条记录外,没有其他方法可以生成结果

SELECT *
FROM   Call
WHERE  NOT EXISTS
  (SELECT *
   FROM   Phone_book
   WHERE  Phone_book.phone_number = Call.phone_number)
ALTER TABLE [dbo].Phone_Book ADD CONSTRAINT [IX_Unique_PhoneNumber] UNIQUE NONCLUSTERED 
(
    Phone_Number
)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = ON) ON [PRIMARY]
GO

一如既往,根据目标数据集分析查询的性能以选择性能最佳的查询是值得的。SQL Optimizers现在已经足够好了,其性能结果常常令人惊讶。这种方法的一个优点(与WOPR的左外联接相比)是,如果
电话簿中有多个匹配行,它可以避免在
呼叫的每行返回多行。也就是说,如果两个表之间存在
1:N
关系,我将从这一个开始,它直接表示意图。如果性能不够好,请确保存在适当的索引。只有这样,才可以尝试不太明显的
左外部联接
,看看它的性能是否更好。这通常是最有效的方法,因为它不会对第二个表执行多次传递。。。希望有些人正在阅读comemnts。我更希望人们描述:除非你是顶级SQL性能专家,否则提前告诉你什么是最快的是相当困难的(取决于你使用的DBMS引擎)。大O符号将很容易告诉你在这种情况下你可以期望什么是最快的。如果两个表之间存在
1:N
关系,请参见和我的评论。或者添加
DISTINCT
,如避免中所示,使用存在-提示在问题标题中左外连接在一般情况下可能是最快的,因为它可以防止子查询的重复执行。不要挑剔,但是我的建议上的子查询返回
select'x'
,而不是
select*
yes-MySQL手册建议这对于“EXISTS”是正常的query@Alnitak:在第二个查询中,您不需要在子查询中选择*
。相反,例如,
SELECT 1
,应该足够漂亮。
call
表中的
id
列的值与
Phone\u book
表中的
id
列的值不同,因此不能加入这些值。类似的方法见WOPR的答案。如果同一列的另一个表中没有数据,这将返回一个表中的数据。这不提供问题的答案。若要评论或要求作者澄清,请在其帖子下方留下评论。-@DennisKriechel更新了查询,使其更具体地针对问题。不确定这是否按原样回答了问题(尽管减号运算符是一个新的加法)。这最终进入了低质量队列-您可能希望增强此答案。
SELECT *
FROM   Call
WHERE  NOT EXISTS
  (SELECT *
   FROM   Phone_book
   WHERE  Phone_book.phone_number = Call.phone_number)
ALTER TABLE [dbo].Phone_Book ADD CONSTRAINT [IX_Unique_PhoneNumber] UNIQUE NONCLUSTERED 
(
    Phone_Number
)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = ON) ON [PRIMARY]
GO