我有以下查询:
SELECT s.id, s.service_measure from service s, user_service_hist ush
WHERE s.id <> ush.service_id
我的 s 表如下所示:
id | service_measure
--------------------
7 | a
8 | b
9 | c
我的 ush 表如下所示:
id | service_id
--------------------
1 | 7
2 | 8
当我运行上述查询时,我希望得到的结果是
id | service_measure
--------------------
9 | c
我的结果是:
id | service_measure
--------------------
8 | b
9 | c
7 | a
9 | c
看起来它正在运行查询 2 次。 ush 表的每一行一次。谁能告诉我为什么会这样?
最佳答案
让我们分解您的查询:
SELECT s.id, s.service_measure
FROM service s, user_service_hist ush
WHERE s.id <> ush.service_id
首先,引擎通过在 from 子句中使用 , 符号来执行您请求的交叉连接。
所以 a,b,c 连接到 1,2 导致
1. 7 a
2. 8 b
3. 9 c
4. 7 a
5. 8 b
6. 9 c
交叉连接将一个表中的每条记录连接到另一个表中的每条记录。这些非常慢,很少需要。想一想,您必须首先获取表 1 中的每条记录并将其与表 2 中的每条记录配对。连接只需匹配 On 等值即可否定交叉连接在生成笛卡尔坐标时所做的所有工作。 (我在工作中很少使用它们;通常在我需要生成测试数据时使用)
然后执行 where 子句,消除 S.ID 和 ush.serivce_ID 匹配的那些。
这消除了上面的第 1 行和第 5 行,这就是为什么您只得到 4 条记录的原因。
要获得预期结果,您需要使用不存在或外部联接而不是交叉联接
SELECT s.id, s.service_measure
FROM service s
LEFT JOIN user_service_hist ush
on S.ID = USH.Service_ID
WHERE ush.Service_ID is null
或
SELECT s.id, s.service_measure
FROM service s
WHERE not exists (Select 1
from user_Service ush
where ush.Service_ID = s.ID)
或(因为您似乎正在学习连接)
SELECT s.id, s.service_measure
FROM user_service_hist ush
RIGHT JOIN service s
on S.ID = USH.Service_ID
WHERE ush.Service_ID is null
(注意我们所做的只是改变连接的顺序和从左到右的单词)右连接表示包括右侧表中的所有记录,并且仅包括左侧表中与右侧匹配的记录。 (大多数人只是重新排列表格,所以它们都是左连接)
我想如果 ush 表很小,in
会起作用,但由于该表不是固定大小,增加该表的记录会导致性能随时间下降。不存在应该是具有适当索引的最有效的长期术语,尽管左连接提供了在需要时从 ush 表中获取额外数据的能力;但对性能略有影响。
关于带有 "<>"运算符的 MySQL SELECT 查询给出了奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40473152/