1. 程式人生 > 其它 >mysql基礎入門總結 複雜查詢

mysql基礎入門總結 複雜查詢

子查詢語句(SubQuery)

## 薪水大於平均薪水的僱員
select * from employees
where salary > (select avg(salary) from employees);

IN 操作符 in 子查詢

## 沒有發票的顧客
select * from clients 
where client_id not in(select distinct client_id from invoices)

子查詢 與 join

select * from clients 
left join invoices using(client_id)
where invoice_id is null

## 也是查詢沒有發票的顧客
## 和使用IN操作符+子查詢語句表達的意思是一樣的
## 但對於表達同樣意思的不同於據來說,既要考慮語句的效能,也要考慮語句的可讀性

ALL 關鍵字 in 子查詢

## 比client id為3的所有發票都大的發票
select * from invoices
where invoice_total > (
	select max(invoice_total) 
	from invoices
	where client_id = 3
)

select * from invoices
where invoice_total > all (
	select invoice_total
	from invoices
	where client_id = 3
)
## 每一條invoice記錄都會和所有的子句返回的值進行比較,返回大於所有值的結果

ANY / SOME 關鍵字 in 子查詢

## 至少有兩個發票的顧客
select * from clients 
where client_id in (
	select client_id from invoices
	group by client_id
	having count(*) >= 2
)

## = any 相當於 in
select * from clients 
where client_id = any (
	select client_id from invoices
	group by client_id
	having count(*) >= 2
)

相關子查詢(Correlated SubQuery)

-- 對於 employees 中的每個記錄e
	-- 計算employees中滿足office_id=e.office_id條件的avg salary
        -- 如果e.salary > avg salary 返回記錄

-- 在這中情況下 子查詢會在每次主查詢的每條記錄執行一次 所以效能會有所降低
select * from employees e
where salary > (
	select avg(salary) from employees
    where office_id = e.office_id
	-- 在這個子查詢中,有個條件是依賴外部查詢的 
)

EXISTS 操作符

## 有發票的顧客
select * from clients c
where exists (	-- 表達的意思和in操作符一樣,只不過當in()中的結果集很大時,會有負面的效能開銷;使用exists相關子查詢更好
	select client_id from invoices
	where client_id = c.client_id -- 相關子查詢
)

SELECT子句中的子查詢

select 
	invoice_id,
	invoice_total,
    (select avg(invoice_total) from invoices) as invoice_average,
    invoice_total - (select invoice_average) as difference -- 不能寫成 invoice_total - invoice_average,因為不能在表示式中使用別名
from invoices

select 
	client_id,
    name,
    (select sum(invoice_total) from invoices
		where client_id = c.client_id) as total_sales,
	(select avg(invoice_total) from invoices) as average,
    (select total_sales - average) as difference
from clients c;

FROM子句中的子查詢

select * 
from (
	select 
		client_id,
		name,
		(select sum(invoice_total) from invoices
			where client_id = c.client_id) as total_sales,
		(select avg(invoice_total) from invoices) as average,
		(select total_sales - average) as difference
	from clients c
) as sales_summary -- FROM子句中子查詢的結果必須要有別名
where total_sales is not null