看下面的例子:
merge into MAGIC_TABLE magic
using (
with UNMAGIC_TABLE as (
select titi, tata from MAGIC_TABLE
and tata='magic2'
)
SELECT titi, tata from UNMAGIC_TABLE
) really_unmagic
on
(
magic.titi = really_unmagic.titi
magic.tata = really_unmagic.tata
and magic.tata='magic1'
)
when not matched then insert (titi, tata)
values
(really_unmagic.titi, 'magic1');
在两个检索相同结果集的表之间,基于等效SELECT *
FROM customers
WHERE EXISTS
(SELECT *
FROM order_details
WHERE customers.customer_id = order_details.customer_id)
;
的查询有哪些区别?
我关注的是技术/性能方面,而不是代码的可读性/可维护性。
答案 0 :(得分:2)
使用EXISTS
子句,选择所有存在至少一个order_details记录的客户。
SELECT *
FROM customers c
WHERE EXISTS (SELECT * FROM order_details od WHERE od.customer_id = c.customer_id);
通过加入,您将再次选择那些客户。但是,只要有一个order_detail即可选择它们。即你会有很多重复。
SELECT c.*
FROM customers c
JOIN order_details od ON c.customer_id = od.customer_id;
您可以使用DISTINCT
从结果中删除重复项,以便仅再次获得每个客户:
SELECT DISTINCT c.*
FROM customers c
JOIN order_details od ON c.customer_id = od.customer_id;
但是为什么只生成所有重复项而只需要再次将其删除呢?不要这样仅在您确实想要加入结果时加入。
我认为比EXISTS
子句更具可读性的另一个选项是IN
子句。这就是我编写查询的方式:
SELECT * FROM customers WHERE customer_id IN (SELECT customer_id FROM order_details);
答案 1 :(得分:1)
EXISTS在逻辑上将按以下方式工作
for x in (select * from customers)
loop
-- check if x.customer_id exists in order_details table.
---if yes
--output the customer tables row
-- else
--ignore
end if;
end loop;
因此,在存在查询中,计划通常将使用嵌套循环(尽管这不是硬性规定)
JOIN查询的逻辑等效性如下
for x in (select * from customers)
loop
--for each row in customer
-- fetch records from order_details which match this condition
select * from order_details where customer_id=x.customerid
end loop;
答案 2 :(得分:1)
EXISTS()
被称为“半连接”。它从JOIN
开始,但是在找到第一个匹配项时停止。因此,EXISTS
比任何等效的JOIN
都要快。
此外,EXISTS( SELECT * ... WHERE ... )
并不真正关心*
。它将使用最佳索引来发现与WHERE
匹配的行的存在与否,然后返回1或0(表示“ true”或“ false”)。
当然,如果LEFT JOIN
将返回0或1行,再也不会返回,那么性能差别就不会太大。除了LEFT JOIN
将返回表中的值。