Sql 相关与不相关子查询

Sql 相关与不相关子查询,sql,oracle,subquery,Sql,Oracle,Subquery,我试图弄清楚如何创建一个使用不相关子查询的语句,以使用相关子查询编写它。以下是使用不相关子查询的Oracle SQL: select Firstname || ', '|| Lastname "Name", title, retail from Customers join orders using (Customer#) join orderitems using (Order#) join books u

我试图弄清楚如何创建一个使用不相关子查询的语句,以使用相关子查询编写它。以下是使用不相关子查询的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;

非常感谢您的帮助。

通常来说,不相关子查询的性能要比相关子查询好得多。然而,您要求一个相关子查询,它将提供与不相关子查询相同的结果。如果我正确理解了您的查询,那么您正试图获取一份客户购买的最昂贵书籍的列表(我假设
retail
books
上的一列)

相关子查询:

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子句只返回没有任何匹配的
ob2
行的
ob1


干杯

谢谢你的帮助,它很有效,帮助我理解两者的区别。