Oracle Database 11g SQL 開發指南學習筆記:子查詢

 

--1.單行子查詢
--查找那些均價不是最高的產品類的id和均價
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;


with p
as
(
select product_type_id,
       avg_price,
       rank() over(order by avg_price desc) rank_num
from 
(
select product_type_id,
       avg(price) as avg_price
from products
group by product_type_id
)
)

select *
from p
where rank_num >= 2;


--每個產品的購買次數
select pd.product_id,
       pd.price,
       p.purchase_count
from products pd
inner join 
  (
    select product_id,
           count(*) as purchase_count
    from purchases
    group by product_id
  )p  --內聯視圖
  on p.product_id = pd.product_id

        
--子查詢不能包含order by,下面的語句會報錯
select *
from products
where price > (select avg(price) 
               from products 
               order by product_id);
               

--2.多行子查詢
--購買過的產品名稱包含字母e的產品
select *
from products
where name like '%e%'
      and product_id in (select product_id from purchases);


--沒有購買過的產品
select 
from products
where product_id not in (select product_id from purchase);


--員工的工資低於任意一個工資級別的最低工資
select employee_id,
       last_name,
       salary
from employees
where salary <  any(select low_salary from salary_grades);


--員工的工資高於所有工資級別的最高工資
select employee_id,
       last_name,
       salary
from employees
where salary > all(select high_salary from salary_grades);


--3.多列子查詢
--查詢那些產品價格是所在產品類中最低的產品
select *
from products
where (product_type_id,price) in (select product_type_id,min(price)
                                  from products
                                  group by product_type_id
                                  );


--4.相關子查詢
--找出產品價格大於同類產品的均價的產品
select product_id,
       product_type_id,
       name,
       price
from products p1
where price > (select avg(price) 
               from products p2 
               where p1.product_type_id = p2.product_type_id);


select p1.product_id,
       p1.product_type_id,
       p1.name,
       p1.price
from products p1
inner join 
      (
        select product_type_id,
               avg(price) as avg_price
        from products 
        group by product_type_id
      )p2
      on p2.product_type_id = p1.product_type_id
         and p1.price > p2.avg_price;


--有下屬的人員
select employee_id,
       last_name
from employees e
where exists (select 1 
              from employees ee
              where e.employee_id = ee.manager_id);


select distinct 
       e.employee_id,
       e.last_name
from employees e
inner join employees ee
        on e.employee_id = ee.manager_id


--沒有購買過的產品
select p.product_id,
       p.name
from products p
where not exists(select 1 
                 from purchases pa
                 where pa.product_id = p.product_id);

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


--找出不包含任何產品的產品類型
select *
from product_types pt
where not exists (select 1 
                  from products p
                  where p.product_type_id = pt.product_type_id );

--這個表面看沒什麼問題,但其實是錯誤的,因爲這裏的多行子查詢的返回值中包含了null
select *
from product_types pt
where product_type_id not in (select product_type_id from products); 

--正確的
select *
from product_types pt
where product_type_id not in (select nvl(product_type_id,0) from products); 


--5.嵌套子查詢
--查找出那些產品所屬品類的均價小於,多次購買的產品所屬品類中最高的均價,的產品的品類和均價
select product_type_id,
       avg(price)
from products
group by product_type_id
having avg(price) < (select max(avg(price))
                     from products
                     where product_id in (select product_id
                                          from purchases
                                          where quantity > 1)
                     group by product_type_id);
                     

--6.包含子查詢的update、delete語句
--把員工號爲4的員工的工資,修改爲所有工資級別的最高工資的平均值
update employees
set salary = (select avg(high_salary)
              from salary_grades)
where employee_id = 4;


--刪除工資大於所有工資級別的最高工資的平均值的員工
delete from employees
where salary > (select avg(high_salary)
                from salary_grades
               );  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章