oracle 开发 第06章 子查询

 2016-01-14

子查询
出现在FROM、WHERE、HAVING子句中的SELECT语句。

一、单行子查询
--对外部SQL不返回结果,或只返回一行。

 1.WHERE子句(嵌套子查询 inline view)

select first_name, last_name
  from customers
 where customer_id =
       (select customer_id from customers where last_name = 'Brown');

select product_id, name, price
  from products
 where price > (select avg(price) from products);

2.HAVING子句

select product_type_id, avg(price)
  from products
 group by product_type_id
having avg(price) < (select max(avg(price))
                       from products
                      group by product_type_id)
 order by product_type_id;

3.FROM子句(内联视图 nested subquery)

select product_id
  from (select product_id from products where product_id < 3);

select prds.product_id, price, purchase_data.product_count
  from products prds,
       (select product_id, count(product_id) product_count
          from purchases
         group by product_id) purchases_data
 where prds.product_id = purchases_data.product_id;

二、多行子查询
--向外部SQL返回一行或多行。
1.IN关键字

select product_id, name from products where product_id in (1, 2, 3);

select product_id, name
  from products
 where product_id in
       (select product_id from products where name like '%e%');

select product_id, name
  from products
 where product_id not in (select product_id from purchases);

2.ANY关键字

select employee_id, last_name
  from employees
 where salary < any (select low_salary from salary_grades)
 order by employee_id;

3.ALL关键字

select employee_id, last_name
  from employees
 where salary > all (select high_salary from salary_grades);

三、多列子查询
--向外部SQL返回多列。

select product_id, product_type_id, name, price
  from products
 where (product_type_id, price) in
       (select product_type_id, min(price)
          from products
         group by product_type_id)
 order by product_id;

四、关联子查询
--引用外部SQL的一列或多列。
--外部查询的每一行都被逐行传递给子查询,直到外部查询中所有行都被处理完,然后返回整个查询结果。

select product_id, product_type_id, name, price
  from products outer_tb
 where price >
       (select avg(price)
          from products inner_tb
         where inner_tb.product_type_id = outer_tb.product_type_id)
 order by product_id;

 1.EXISTS关键字

 select employee_id, last_name
  from employees outer_tb
 where exists (select employee_id
          from employees inner_tb
         where inner_tb.manager_id = outer_tb.employee_id)
 order by employee_id;

select employee_id, last_name
  from employees outer_tb
 where exists (select 1
          from employees inner_tb
         where inner_tb.manager_id = outer_tb.employee_id)
 order by employee_id;

2.NOT EXISTS关键字

select product_id, name
  from products outer_tb
 where not exists (select 1
          from purchases inner_tb
         where inner_tb.product_id = outer_tb.product_id)
 order by product_id;

 3.EXISTS、NOT EXISTS、IN、NOT IN 

--EXISTS性能比IN高,尽可能使用EXISTS,而不是IN
--当值列表包含空值,NOT EXISTS返回true,NOT IN返回false
--子查询返回行包含空值,NOT EXISTS操作符返回false
select product_type_id, name
  from product_types outer_tb
 where not exists
 (select 1
          from products inner_tb
         where inner_tb.product_type_id = outer_tb.product_type_id)
 order by product_type_id;
--子查询返回行包含空值,NOT IN操作符返回false
select product_type_id, name
  from product_types
 where product_type_id not in (select product_type_id from products)
 order by product_type_id;

select product_type_id, name
  from product_types
 where product_type_id not in
       (select nvl(product_type_id, 0) from products)
 order by product_type_id;

五、嵌套子查询

--出现在WHERE子句的SELECT
select product_type_id, avg(price)
  from products
 group by product_type_id
having avg(price) < (select max(avg(price))
                       from products
                      where product_type_id in
                            (select product_type_id
                               from purchases
                              where quantity > 1)
                      group by product_type_id)
 order by product_type_id;

六、UPDATE、DELETE子查询
1.UPDATE语句

update employees
   set salary =
       (select avg(high_salary) from salary_grades)
 where employee_id = 4);

2.DELETE语句

delete from employees
 where salary > (select avg(high_salary) from salary_grades);

七、WITH语句

with customer_purchases as
 (select cu.customer_id, sum(pr.price * pu.quantity) as purchase_total
    from customers cu, purchases pu, products pr
   where cu.cusotmer_id = pr.product_id
   group by cu.customer_id)
select * from customer_purchases order by customer_id;

with customer_purchases as
 (select cu.customer_id, sum(pr.price * pu.quantity) as purchase_total
    from customers cu, purchases pu, products pr
   where cu.cusotmer_id = pr.product_id
     and pu.product_id = pr.product_id
   group by cu.customer_id),
average_purchase as
 (select sum(purchase_total) / count(*) as average from customer_purchases)
select *
  from customer_purchases
 where purchase_total < (select average from average_purchase)
 order by customer_id;

 

【参考资料】

[1] Jason Price.精通Oracle Database 12c SQL&PLSQL编程(第3版).[M].北京:清华大学出版社,2014

posted @ 2016-01-12 16:13  岑亮  阅读(272)  评论(0编辑  收藏  举报