加入以替换子查询

时间:2013-05-30 15:18:06

标签: sql oracle join

我几乎是数据库查询的新手。 但是,我确实理解为什么以及如何相关子查询昂贵且最好避免。 给出以下简单示例 - 有人可以帮助替换联接以帮助理解它如何得分更好:

SQL> select
  2    book_key,
  3    store_key,
  4    quantity
  5  from
  6    sales s
  7  where
  8    quantity < (select max(quantity)
  9                 from sales
 10                 where book_key = s.book_key); 

除了加入之外,我们还有什么其他选择来避免子查询。

3 个答案:

答案 0 :(得分:0)

在这种情况下,在对表的单次访问中使用窗口函数应该更好 - 就像这样:

with s as
(select book_key, 
        store_key, 
        quantity, 
        max(quantity) over (partition by book_key) mq
 from sales)
select book_key, store_key, quantity
from s 
where quantity < s.mq

答案 1 :(得分:0)

使用Common Table Expressions(CTE)将允许您执行单个主SELECT语句并将结果存储在临时结果集中。然后可以自我引用和访问数据多次,而不需要再次执行初始SELECT语句,并且不需要可能昂贵的JOIN。此解决方案还使用ROW_NUMBER()OVER子句根据数量按降序对匹配的BOOK_KEY进行编号。然后,您将只包含数量小于每个BOOK_KEY的最大数量的记录。

with CTE as
(
  select 
    book_key, 
    store_key, 
    quantity,
    row_number() over(partition by book_key order by quantity desc) rn
  from sales
)
select 
  book_key, 
  store_key, 
  quantity 
from CTE where rn > 1;

工作演示:http://sqlfiddle.com/#!3/f0051/1

答案 2 :(得分:-1)

除了加入之外,我们还有什么其他选择来避免子查询。

你使用这样的东西:

SELECT select max(quantity)
INTO @myvar 
from sales
where book_key = s.book_key

select book_key,store_key,quantity
from sales s
where quantity < @myvar