--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
);