相关与不相关子查询

Correlated vs uncorrelated subquery

我正在尝试弄清楚如何创建一个使用不相关子查询的语句来使用相关子查询来编写它。这是使用不相关子查询的 Oracle SQL:

select 
    Firstname || ', '|| Lastname "Name", title, retail
from 
    Customers 
join 
    orders using (Customer#) 
join 
    orderitems using (Order#)                 
join 
    books using (Isbn)
where 
    (Customer#, retail) in (select Customer#,  max(retail)
                            from books 
                            join orderitems using (isbn) 
                            join Orders using (order#) 
                            join Customers using (Customer#)
                            group by Customer#)                 
order by  
    Firstname, Lastname, title;

如有任何帮助,我们将不胜感激。

通常来说,不相关的子查询会比相关的子查询执行得更好。然而,您要求一个相关子查询将提供与您的非相关子查询相同的结果。如果我对您的查询的理解正确,那么您正在尝试获取购买了最昂贵书籍的客户列表(我假设 retailbooks 上的一列)。

相关子查询:

select Firstname || ', '|| Lastname "Name", title, retail
  from Customers c 
  join orders using (Customer#) 
  join orderitems using (Order#)                 
  join books using (Isbn)
where retail = (
  select max(retail)
    from books b2 
    join orderitems using (isbn) 
    join Orders o using (order#) 
   where o.Customer# = c.Customer#
)                 
order by  Firstname, Lastname, title;

该查询可能 运行 比您的查询慢得多。它实际上将对外部查询的每一行执行内部查询。

如果您正在寻找运行速度更快的查询,请尝试以下操作:

with order_books as
(
  select Customer#, title, retail
    from orders 
    join orderitems using (Order#)                 
    join books b1 using (Isbn)
)
select Firstname || ', '|| Lastname "Name", ob1.title, ob1.retail
  from Customers
  join order_books ob1 using (Customer#)
  left outer join order_books ob2
    on (   ob2.Customer# = ob1.Customer# 
       and ob2.retail > ob1.retail )
 where ob2.Customer# is null             
 order by  Firstname, Lastname, ob1.title;

这个查询不包含子查询,它应该比上面的任何一个查询都快得多。它使用外部联接来查找零售价值高于当前 ob1 行的 ob2 行。然后,它使用 WHERE 子句仅 return ob1 行没有任何匹配的 ob2 行。

干杯!