oracle SQL多表查詢
SQL多表查詢
1、集合理論
1.1 什麼是集合
具有某種特定性質的事物的總體。
集合的特性:無序性、互異性、確定性。
一個集合可以小到從一個表中取出一行中的一列。 1 rows 1 cols
也可以不返回任何行--空集 0 rows n cols
也可以有多個列,這些列可以是從多個表中取出的多行資訊。 m rows n cols
結果集中的每一行就是這個集合的一個元素。
1.2集合運算
1)交
用來得到兩個或多個不同集合的共同元素。
A ∩ B = {e∈A 且 e∈B}
2)減
用來查詢在一個集合中出現過,而在另一個集合中沒有出現的元素。
A - B = {e|e∈A 且 e!∈B}
3)並
用來合併兩個或多個相類似的集合。
A ∪ B = {e∈A 或 e∈B}
1.3 交
INTERSECT
Intersect
SELECT p.product_id,p.product_type_id,p.name
FROM products p
intersect
SELECT m.prd_id,m.prd_type_id,m.name
FROM more_products m
同時在A,B表中出現
4.4差
MINUS
SELECT p.product_id,p.product_type_id,p.name
FROM products p
minus
SELECT m.prd_id,m.prd_type_id,m.name
FROM more_products m
在A表中存在,而在B表中不存在的資料
select a.*,rownum from
(select * from employees2 e order by e.salary desc) a where rownum <=10
minus
select a.*,rownum from
(select * from employees2 e order by e.salary desc) a where rownum <=2
4.5並
--使用union all操作符
--union all操作符返回查詢所檢索出的所有行,包括重複行。
SELECT p.product_id,p.product_type_id,p.name
FROM products p
union all
SELECT m.prd_id,m.prd_type_id,m.name
FROM more_products m
select * from products
select * from more_products
--union all中間不能包含order by子句
SELECT product_id,product_type_id,NAME
FROM products
--ORDER BY 1 DESC
UNION ALL
SELECT prd_id,prd_type_id,NAME
FROM more_products
ORDER BY 1 DESC;
--使用union操作符
--union操作符返回查詢檢索出的所有非重複行
SELECT product_id,product_type_id,NAME
FROM products
UNION
SELECT prd_id,prd_type_id,NAME
FROM more_products
ORDER BY 1 DESC;
課堂筆記
select p.product_id,p.product_type_id,p.name from products p;
select mp.prd_id,mp.prd_type_id,mp.name from more_products mp;
----交集
select p.product_id,p.product_type_id,p.name from products p
intersect
select mp.prd_id,mp.prd_type_id,mp.name from more_products mp;
----查詢出被購買㢧的產品,並且價格低於20元的產品id
select p.product_id from products p where p.price<20
intersect
select distinct pr.product_id from purchases pr;
--多表查詢
select distinct p.product_id from products p,purchases pr where
p.product_id=pr.product_id and p.price<20;
--in 方法
select p.product_id from products p where p.price <20 and
p.product_id in (select distinct pr.product_id from purchases pr);
------並集 union
select p.product_id,p.product_type_id,p.name from products p
union all
select mp.prd_id,mp.prd_type_id,mp.name from more_products mp;
---查詢出工資最高與工資最低的員工的資訊
select * from
(select * from employees2 e order by e.salary desc) where rownum=1
union
select * from
(select * from employees2 e order by e.salary) where rownum=1;
---減集 minus
select p.product_id,p.product_type_id,p.name from products p
minus
select mp.prd_id,mp.prd_type_id,mp.name from more_products mp;
--------------------按照工資排序,查詢出第六名到第十名的員工資訊
select * from
(select * from employees2 e order by e.salary desc)
where rownum<=10
minus
select * from
(select * from employees2 e order by e.salary desc)
where rownum<=5
---查詢出產品的id號,產品的名字,產品的價格,產品型別名。
select * from products;
select * from product_types;
select p.product_id,p.name,p.price,pt.name from products p,product_types pt
where p.product_type_id = pt.product_type_id
union
select p.product_id,p.name,p.price,null
from products p where p.product_type_id is null;
2 內連線
2.1什麼是連線
將資料庫中的兩個或多個表組合起來。把不同表的資料通過條件連線在一起。
把多個表聯合或者連線起來才能得到想要的結果。
在關係資料庫管理系統中,表建立時各資料之間的關係不必確定,常把一個實體的所有資訊存放在一個表中。
當檢索資料時,通過連線操作查詢出存放在多個表中的不同實體的資訊。
連線操作給使用者帶來很大的靈活性,他們可以在任何時候增加新的資料型別。
為不同實體建立新的表,爾後通過連線進行查詢。
連線在SQL92標準中用join關鍵字來實現,JOIN 關鍵字操作本質上來說
也是一種集合的交運算,它可以指定一些列,系統只要求這些列匹配,
從而完成集合的連線。
在一個SQL語句中,JOIN 作為 FROM 子句的一部分。
JOIN 定義了一個邏輯表,它是兩個表或結果集連線後的結果。
2.2連線型別
SQL-92標準所定義的FROM子句的連線語法格式為:
FROM join_table join_type join_table
[ON (join_condition)]
--join_table
其中join_table指出參與連線操作的表名,連線可以對同一個表操作,
也可以對多表操作,對同一個表操作的連線又稱做自連線。
--join_type
join_type 指出連線型別,可分為三種:內連線、外連線和交叉連線。
1)內連線(INNER JOIN)
使用比較運算子進行表間某(些)列資料的比較操作,
並列出這些表中與連線條件相匹配的資料行。
根據所使用的比較方式不同,內連線又分為等值連線、自然連線和不等連線三種。
2)外連線(OUTER JOIN)
與內連線不同的是,外連線不只列出與連線條件相匹配的行,
而是列出左表(左外連線時)、右表(右外連線時)或兩個表(全外連線時)中所有符合搜尋條件的資料行。
外連線分:
左外連線(LEFT OUTER JOIN 或 LEFT JOIN)、
右外連線(RIGHT OUTER JOIN 或 RIGHT JOIN)和
全外連線(FULL OUTER JOIN 或 FULL JOIN)三種。
3)交叉連線(CROSS JOIN)
返回連線表中所有資料行的笛卡爾積。
(若表A有m行,表B有n行,則交叉連線後的結果集有:m*n 行)
對SQL92標準來說,交叉連線(CROSS JOIN)不能使用有 ON 或 USING 關鍵字;
對於SQL89標準來說,就是不帶where搜尋條件的連線。
--SQL89語法
S product_types;
SELECT * FROM products, product_types;
--join_condition
連線操作中的ON (join_condition) 子句指出連線條件,
它由被連線表中的列和比較運算子、邏輯運算子等構成。
若兩個表的連線列列名相同,則可以簡寫為:
USING(column_name)
--查詢出產品的名,產品型別名,產品價格
select p.product_type_id,p.name pro_name,
(select pt.name from product_types pt where pt.product_type_id=p.product_type_id) type_name,p.price
from products p;
2.3內連線
1)定義及型別
只返回那些同時和兩個表或結果集匹配的資料行。
內連線基於連線謂詞將兩張表(如 A 和 B)的列組合在一起,產生新的結果表。
查詢會將 A 表的每一行和 B 表的每一行進行比較,並找出滿足連線謂詞的組合。
當連線謂詞被滿足,A 和 B 中匹配的行會按列組合(並排組合)成結果集中的一行。
連線產生的結果集,可以定義為首先對兩張表做笛卡爾積(交叉連線),
即將 A 中的每一行和 B 中的每一行組合,然後返回滿足連線謂詞的記錄。
內連線分三種:
(1)等值連線:
在連線條件中使用等於號(=)運算子比較被連線列的列值,其查詢結果中列出被連線表中的所有列,包括其中的重複列。
(2)不等連線:
在連線條件使用除等於運算子以外的其它比較運算子比較被連線的列的列值。這些運算子包括>、>=、<=、<、<>。
(3)自然連線:
在連線條件中使用等於(=)運算子比較被連線列的列值,但它使用選擇列表指出查詢結果集合中所包括的列,並刪除連線表中的重複列。
2)語法
SELECT value_expression
FROM table_name
INNER JOIN table_name
ON search_condition;
OR
SELECT value_expression
FROM table_name
INNER JOIN table_name
USING(column_name);
--SQL89語法
SELECT value_expression
FROM table_name, table_name
WHERE search_condition;
寫一條sql語句
查詢出產品名字,產品型別名,產品價格?
如同可以在 WHERE 子句中使用搜索條件一樣,在 ON 子句中也可以使用搜索條件。
SELECT * FROM products;
SELECT * FROM product_types;
SELECT products.*,product_types.*
FROM products
inner join product_types
on products.product_type_id = product_types.product_type_id;
SELECT products.name, product_types.name
FROM products
inner join product_types
on products.product_type_id = product_types.product_type_id;
3)等值連線
ON 子句中搜索條件為 = 比較操作符
SELECT * FROM products;
SELECT * FROM purchases;
SELECT *
FROM products pd
INNER JOIN purchases pc
ON pd.product_id = pc.product_id;
4)不等連線
ON 子句中的搜尋條件為 <> > >= < <= 比較操作符
SELECT * FROM products;
SELECT * FROM product_types;
SELECT products.*,product_types.*
FROM products
inner join product_types
on nvl(products.product_type_id,2) <> product_types.product_type_id;
5) NATURAL INNER JOIN
連線的表中有相同的列名(一個或多個),系統預設使用這些同名的列作為相等連線條件。
value_expression中不能使用表別名。
SELECT * FROM products;
SELECT * FROM purchases;
SELECT customer_id, product_id, price, quantity
FROM purchases natural inner join products;
相當於
select a.product_id,b.customer_id,a.price,b.quantity
from products a inner join purchases b on a.product_id = b.product_id
6)表別名
可以對連線的表加一個別名,注意與列別名的區別,不能加 AS 。
SELECT p.name, pt.name
FROM products P
INNER JOIN product_types pt
ON p.product_type_id = pt.product_type_id;
7)SELECT 語句巢狀
SELECT value_expression
FROM (select_statement)
INNER JOIN (select_statement)
ON search_condition;
OR
SELECT value_expression
FROM (select_statement)
INNER JOIN (select_statement)
USING(column_name);
--查詢出產品價格大於15元並且被購買數量超過1個的產品。
SELECT * FROM products;
SELECT * FROM purchases;
SELECT product_id, name, price
FROM products
WHERE product_type_id IS NOT NULL
AND price > 15
SELECT product_id, customer_id, quantity
FROM purchases
WHERE quantity > 1
SELECT pd.product_id, pd.name, pc.customer_id, pc.quantity
FROM (SELECT product_id, name, price
FROM products
WHERE product_type_id IS NOT NULL
AND price > 15) pd
INNER JOIN (SELECT product_id, customer_id, quantity
FROM purchases
WHERE quantity > 1) pc
ON pc.product_id = pd.product_id;
--查詢出產品價格大於15元並且被購買數量超過1個的產品。
SELECT * FROM products;
SELECT * FROM purchases;
select p.product_id,p.name from products p inner join purchases pr on p.product_id=pr.product_id
where pr.quantity>1 and p.price >15;
select a.product_id,a.name from
(select * from products p where p.price>15) a inner join
(select * from purchases pr where pr.quantity>1) b on a.product_id=b.product_id;
select p.product_id,p.name from products p where p.price>15 and p.product_id
in(select pr.product_id from purchases pr where pr.quantity>1);
select p.product_id,p.name from products p where p.product_id in
(select p.product_id from products p where p.price>15
intersect
select pr.product_id from purchases pr where pr.quantity>1);
8)JOIN 和 JOIN 巢狀
SELECT value_expression
FROM (table_name INNER JOIN table_name ON search_condition)
INNER JOIN
table_name
ON search_condition;
SELECT
SELECT value_expression
FROM table_name
INNER JOIN
(table_name INNER JOIN table_name ON search_condition)
ON searcha_condition;
select * from orders;
select * from customers c;
select * from employees e;
--查詢出訂單號小於100,下訂單的客戶名與處理訂單的僱員名
select a.ordernumber,a.custfirstname,a.custlastname,e.empfirstname,e.emplastname from
(select * from orders o inner join customers c on o.customerid=c.customerid) a
inner join employees e on a.employeeid = e.employeeid where a.ordernumber<100;
select o.ordernumber,c.custfirstname,c.custlastname,e.empfirstname,e.emplastname
from (orders o inner join customers c on o.customerid=c.customerid)
inner join employees e on o.employeeid=e.employeeid where o.ordernumber<100;
select o.ordernumber,c.custfirstname,c.custlastname,e.empfirstname,e.emplastname
from (orders o inner join customers c on o.customerid=c.customerid and o.ordernumber<100)
inner join employees e on o.employeeid=e.employeeid;
3 外連線
3.1什麼是外連線
返回的不僅和所指定的判斷標準匹配的行資訊,同時也需要把連線體中不匹配的資訊返回。
OUTER JOIN 也用於計算兩個集合的差值。
內連線時,返回查詢結果集合中的僅是符合連線條件的行。
而採用外連線時,它返回到查詢結果集合中的不僅包含符合連線條件的行,
而且還包括左表(左外連線時)、右表(右外連線時)或兩個連線表(全外連線)中的所有資料行。
1)左外連線:
左外連線的結果集包括 LEFT OUTER 子句中指定的左表的所有行,而不僅僅是聯接列所匹配的行。
如果左表的某行在右表中沒有匹配行,則在相關聯的結果集行中右表的所有選擇列表的列值均為空值。
2)右外連線:
右外連線是左外連線的反向聯接。將返回右表的所有行。
如果右表的某行在左表中沒有匹配行,則將為左表的列表值返回空值。
3)完整外連線:
完整外連線返回左表和右表中的所有行。
當某行在另一個表中沒有匹配行時,則另一個表的選擇列表列值包含空值。
如果表之間有匹配行,則整個結果集行包含基表的資料值。
3.2左/右外連線
1)定義
獲取一個表或結果集中所有行以及另一個表或結果集中所有匹配的行
出現在 JOIN 前的第一個表為左表,JOIN 後的第二個表為右表
理解:
左外連線:先對A表和B表做內連線,再將A表沒有匹配的行加入到結果集中得到最終的結果集。
右外連線:先對A表和B表做內連線,再將B表沒有匹配的行加入到結果集中得到最終的結果集。
2)語法
SELECT value_expression
FROM table_name
LEFT OUTER JOIN
table_name
ON search_condition;
SELECT value_expression
FROM table_name
RIGHT OUTER JOIN
table_name
ON search_condition;
--SQL89語法
--左外連線
SELECT value_expression
FROM left_table, right_table
WHERE left_table.column = right_table.column(+);
--右外連線
SELECT value_expression
FROM left_table, right_table
WHERE left_table.column(+) = right_table.column;
3)左外連線
1、
SELECT * FROM products;
SELECT * FROM product_types;
預置條件
update products set products.product_type_id='' where products.product_id=11;
insert into product_types values(6,'evd');
select * from products p inner join product_types pt on p.product_type_id =pt.product_type_id;
select * from products p left outer join product_types pt on p.product_type_id =pt.product_type_id;
2、
SELECT * FROM products;
SELECT * FROM purchases;
SELECT p.product_id lpi, p.name lname, pc.quantity rquantity
FROM products p
left OUTER JOIN purchases pc
ON p.product_id = pc.product_id
ORDER BY 1;
3、
SELECT * FROM products;
SELECT * FROM purchases;
SELECT p.product_id lpi, p.name lname, pc.quantity rquantity
FROM products p
left OUTER JOIN purchases pc
ON p.product_id = pc.product_id AND p.product_id <> 1
ORDER BY 1;
4、
SELECT p.product_id lpi, p.name lname, pc.quantity rquantity
FROM products p
LEFT OUTER JOIN purchases pc
ON p.product_id = pc.product_id
WHERE p.product_id <> 1
ORDER BY 1;
查詢出沒有被購買過的產品的資訊
select p.* from (products p left join purchases pr
on p.product_id=pr.product_id) where pr.product_id is null;
4)右外連線
1、
SELECT * FROM products;
SELECT * FROM product_types;
SELECT p.product_id lpi, p.name lname, pt.name rname
FROM products p
RIGHT OUTER JOIN product_types pt
ON p.product_type_id = pt.product_type_id
ORDER BY 1;
2、
SELECT p.product_id lpi, p.name lname, pt.name rname,p.product_type_id,pt.product_type_id
FROM products p
RIGHT OUTER JOIN product_types pt
ON p.product_type_id = pt.product_type_id
AND pt.name <> 'Video'
ORDER BY 1;
5)SELECT 語句巢狀
SELECT value_expression
FROM (select_statement)
OUTER LEFT/RIGHT JOIN
(select_statement)
ON search_condition;
1、
SELECT * FROM products;
SELECT * FROM purchases;
SELECT pd.product_id, pd.name, pd.name, pc.customer_id, pc.quantity
FROM (SELECT product_id, name, price
FROM products
WHERE product_type_id IS NOT NULL
AND price > 15) pd
LEFT OUTER JOIN (SELECT product_id, customer_id, quantity
FROM purchases
WHERE quantity > 1) pc
ON pc.product_id = pd.product_id;
2、
SELECT * FROM products;
SELECT * FROM product_types;
SELECT pd.product_id,pd.product_type_id, pd.name, pd.name,pt.product_type_id, pt.name
FROM (SELECT product_id, product_type_id, name, price
FROM products
WHERE price > 15) pd
RIGHT OUTER JOIN (SELECT product_type_id, NAME
FROM product_types
WHERE product_type_id <> 1) pt
ON pd.product_type_id = pt.product_type_id;
--哪些使用者沒有購買過Supernova產品(select巢狀)
SELECT * FROM customers;
SELECT * FROM products;
SELECT * FROM purchases;
--購買過Supernova 的顧客id
select pr.customer_id from products p inner join purchases pr on p.product_id=pr.product_id and p.name='Supernova';
沒有購買過Supernova產品的顧客
select * from customers c where c.customer_id not in
(select pr.customer_id from products p inner join purchases pr on p.product_id=pr.product_id and p.name ='Supernova')
另一種寫法
select c.customer_id,c.first_name,c.last_name,pp.product_id from customers c left outer join
(select p.product_id,pc.customer_id from products p inner join purchases pc on p.product_id =pc.product_id and p.name ='Supernova') pp
on c.customer_id = pp.customer_id where pp.product_id is null ;
6)JOIN 和 JOIN 巢狀
SELECT value_expression
FROM (table_name OUTER LEFT/RIGHT JOIN table_name ON search_condition)
LEFT/RIGHT OUTER JOIN
table_name
ON search_condition;
SELECT value_expression
FROM table_name
LEFT/RIGHT OUTER JOIN
(table_name LEFT/RIGHT OUTER JOIN table_name ON search_condition)
ON search_condition;
--哪些使用者沒有購買過Supernova產品(join巢狀)
SELECT * FROM customers;
SELECT * FROM products;
SELECT * FROM purchases;
select c.customer_id,c.first_name,c.last_name from customers c left outer join(products p inner join purchases pr on p.product_id =pr.product_id and p.name='Supernova')
on c.customer_id =pr.customer_id and p.product_id is null;
3.3完全外連線
1)定義
是左連線和右連線兩者的結合
2)語法
SELECT value_expression
FROM table_name FULL OUTER JOIN table_name ON search_condition;
SELECT * FROM products;
SELECT * FROM product_types;
SELECT p.product_id lpi, p.name lname, pt.name rname
FROM products p
FULL OUTER JOIN product_types pt
ON p.product_type_id = pt.product_type_id
ORDER BY 1;
總結:
交叉連線->返回符合邏輯表示式的行(內連線)->加入左表不符合邏輯表示式的行(左外連線)
交叉連線->返回符合邏輯表示式的行(內連線)->加入右表不符合邏輯表示式的行(右外連線)
交叉連線->返回符合邏輯表示式的行(內連線)->加入右表不符合邏輯表示式的行(右外連線)->加入左表不符合邏輯表示式的行(左外連線)->返回結果集(全外連線)
4 子查詢
4.1什麼是子查詢
1)定義
子查詢就是一個select表示式,這個表示式被嵌入select語句的一個子句中,
組成最終的查詢語句。
SQL標準中定義了三種不同型別的子查詢:
(1)行子查詢(ROW subquery)
一個嵌入的select表示式,返回多個列以及返回的行數不超過1。 n cols 0/1 rows
(2)表子查詢(TABLE subquery)
一個嵌入的select表示式,返回單個或多個列,行數任意。 n cols m rows
(3)標量子查詢(scalar subquery)
一個嵌入的select表示式,返回單行單列值。 1 cols 1 rows
2)行子查詢
SQL標準中規定了一個行值建構函式可以作為where、having或on子句中查詢條件謂詞的一部分。
oracle不支援。
比如:
SELECT * FROM products;
SELECT * FROM products
WHERE (product_id, price) > (1, 20);
4.2作為列表達式的子查詢
1)句法
SELECT value_expression FROM table_name;
value_expression:
運算元:
Literal_VALUE
COLUMN_REFERENCE
FUNCTION
(select_expression)
(value_expression)
操作符:
+
-
*
/
||
2)例子
SELECT * FROM customers;
SELECT * FROM products;
SELECT * FROM purchases;
--在select子句列表中
SELECT c.first_name,
c.last_name,
( SELECT COUNT(*) FROM purchases p,customers c WHERE p.customer_id = c.customer_id ) pchcnt
FROM customers c;
與下面的語句是不一樣的。
SELECT c.first_name,
c.last_name,
(SELECT COUNT(*) FROM purchases p WHERE p.customer_id = c.customer_id) pchcnt
FROM customers c;
上面的語句,c.customer_id 是customer表中查詢的值,一一匹配
而下面的語句,內部的customer表與外部的customer表不是一個概念。
--產品id,產品名字,產品型別名,產品價格
select p.product_id,p.name,
(select pt.name from product_types pt where pt.product_type_id=p.product_type_id) type_name,
p.price from products p;
--在where搜尋條件中
SELECT * FROM products;
SELECT * FROM purchases;
被購買的產品ID有
select distinct ps.product_id from purchases ps
寫出被購買過的產品的名字與價格
SELECT p.product_id, p.name, p.price
FROM products p
WHERE p.product_id in
(select distinct ps.product_id from purchases ps);
三表查詢
select c.first_name,p.name,p.price from products p inner join purchases pu
on p.product_id = pu.product_id
inner join customers c on c.customer_id = pu.customer_id
4.3作為過濾器的子查詢
1)句法
SELECT value_expression
FROM table_reference
WHERE search_condition
GROUP BY value_expression
HAVING search_condition
其中
table_reference包括 ON search_condition
WHERE search_condition
HAVING search_condition中都可以使用子查詢。
2)子查詢的特定謂詞關鍵字
(1)集合成員 IN /NOT IN
SELECT value_expression
FROM table_reference
WHERE value_expression [NOT] IN (select_expression)/(value_expression);
SELECT * FROM products;
SELECT * FROM purchases;
被購買過的產品資訊
SELECT *
FROM products
WHERE product_id IN (SELECT product_id FROM purchases);
沒被購買過產品的資訊
SELECT *
FROM products
WHERE product_id NOT IN (SELECT product_id FROM purchases);
SELECT *
FROM products
WHERE (product_id, product_type_id) IN
(SELECT product_id, quantity FROM purchases);
(2)定量比較謂詞 ALL ANY
ANY = SOME
SELECT value_expression
FROM table_reference
WHERE value_expression =/<>/</<=/>/>= ALL/ANY/SOME (select_expression);
SELECT *
FROM products
WHERE product_id = ANY (SELECT product_id FROM purchases);
SELECT *
FROM products
WHERE product_id > ANY (SELECT product_id FROM purchases);
大於any :大於最小的,
小於any :小於最大的
SELECT *
FROM products
WHERE product_id > ALL (SELECT product_id FROM purchases);
小於all ,小於最小的
大於all,大於最大的
--查詢出工資低於各部門平均工資的員工
select * from employees2 e where e.salary <all(
select avg(e.salary) from employees2 e group by e.division_id);
select * from employees2 e where e.salary <
(select min(avg(e.salary)) from employees2 e group by e.division_id)
(3)存在謂詞 EXISTS / NOT EXISTS
EXISTS謂詞只注重子查詢是否返回行。如果子查詢返回一個或多個行,謂詞返回為true,否則返回false。
EXISTS搜尋條件並不真正地使用子查詢的結果。它僅僅測試子查詢是否產生任何結果。
可以使用 NOT EXISTS 形式顛倒 EXISTS 測試的邏輯。
在此情況下,如果子查詢沒有生成任何行,則該測試返回 true,否則返回 false。
SELECT * FROM products;
SELECT * FROM purchases;
SELECT *
FROM products p
WHERE EXISTS
(SELECT * FROM purchases pc,products p WHERE p.product_id = pc.product_id);
SELECT *
FROM products p
WHERE NOT EXISTS
(SELECT * FROM purchases pc WHERE p.product_id = pc.product_id);
select p.product_id,p.name,p.price from products p where exists
(select * from purchases pr where pr.product_id =p.product_id and pr.quantity>1)
關聯子查詢
SELECT * FROM products;
SELECT * FROM purchases;
--exists 與 not exists 謂詞
select * from products where not exists (select * from purchases);
---查詢出沒有被購買過的產品資訊
--1 not in
select * from products p where p.product_id not in
(select distinct pr.product_id from purchases pr);
--2 左外連線
select p.* from products p left join purchases pr
on p.product_id = pr.product_id where pr.product_id is null;
--3 exists 子查詢
select * from products p where not exists (select * from purchases pr where pr.product_id =p.product_id);
子查詢可包含對父語句中所定義物件的引用。這稱為外部引用。包含外部引用的子查詢稱為相關子查詢。
相關子查詢無法獨立於外部查詢進行計算,因為子查詢使用了父語句的值。
即,會針對父語句中的每一行來執行子查詢。因此,子查詢的結果取決於父語句中正在計算的活動行。
多表查詢
僱員表與部門表
select * from employees2 e,divisions d where e.division_id = d.division_id
select e.employee_id,division_id,e.first_name from employees2 e,divisions d
where e.division_id = d.division_id 為什麼會報錯
select e.employee_id,e.division_id,d.division_id,e.first_name from employees2 e,divisions d where e.division_id = d.division_id
三表
cselect * from employees2 e,divisions d,jobs j where e.division_id = d.division_id and e.job_id = j.job_id
--課堂練習
1)山地車的平均零售價格是多少?(Bikes)
2)最近一次訂貨的日期是哪一天?
3)第8號訂單的訂貨總額是多少?
4)列出每一個供應商名字以及每一個供應商的平均發貨天數;
5)列出每一個供應商,並且當其平均發貨天數大於所有供應商平均發貨天數時列出其平均發貨天數;
6)列出每一種產品的產品名和總銷售額;
--5)列出每一種產品的產品名和總銷售額;
--6)列出每一類產品的產品類別名和總銷售額;
--7)列出每一個訂單的訂單號和總銷售額;
8)有多少次訂購只定了一種產品?
--1
select c.categorydescription,avg(p.retailprice)
from products p,categories c
where p.categoryid =c.categoryid and c.categoryid =2
group by c.categorydescription;
--2
select a.categorydescription,b.avg_price from categories a,
(select pr.categoryid,avg(pr.retailprice) as avg_price
from products pr group by pr.categoryid having pr.categoryid =2) b
where a.categoryid =2;
select c.categorydescription,
(select avg(p.retailprice) from products p where p.categoryid =2)
from categories c
where c.categoryid =2
查詢出工資最多的三個人工資
select a.employee_id,a.salary,rownum from
(select e.employee_id,e.salary from employees2 e order by e.salary desc) a where rownum<=3;
查詢出工資第三到第十名的工資
select * from
(select a.employee_id,a.salary,rownum rn from
(select e.employee_id,e.salary from employees2 e order by e.salary desc) a) b where b.rn >=3 and b.rn<=10;
如何從一張表總獲取一個隨便記錄
select pp.*,rownum from
(select p.* from products p order by dbms_random.value) pp where rownum =1;
select * from purchases;
select * from products;
--寫出被購買過的產品的名字與價格
select p.name,p.price from products p where p.product_id
in(select distinct pr.product_id from purchases pr);
select distinct p.name,p.price from products p,purchases pr where p.product_id=pr.product_id;
--寫出沒有被購買過的產品的名字與價格
select p.name,p.price from products p where p.product_id
not in(select distinct pr.product_id from purchases pr);
select p.name,p.price from products p left outer join purchases pr on p.product_id =pr.product_id
where pr.product_id is null;
練習題:
--1 查詢出產品的ID號,產品的名字,產品的零售價,產品的型別名。
--2、查詢出訂單號,下訂單的顧客名字,以及處理的僱員的名字。
--3、查詢出產品的ID號,供應該產品的供應商的名字,以及該產品的批發價。
--4、查詢出產品的名字,供應該產品的供應商的名字,以及該產品的批發價
--5、查詢出產品id為8的產品銷售總額
--6、查詢出產品的ID號,以及每個產品的總銷售額。
--6、查詢出產品的名字,以及每個產品的總銷售額。
--7、查詢出銷售總額超過2萬的產品的名字以及銷售額。
--8、查詢出每一類產品的型別名,以及每類產品的銷售總額。
--9、查詢出訂單號,以及每個訂單號訂購了多少種產品
--10、查詢訂購的產品數超過5個的訂單號以及訂購的產品種類數。
--11、查詢出訂購產品種類數超過5個的訂單號以及訂單總額。
--12、查詢出每個僱員的ID號以及每個僱員的銷售額
--13 查詢出每個僱員的ID號,僱員的名字,以及每個僱員的銷售額
--14、查詢僱員與顧客住在同一個城市的城市名字、顧客的名字以及僱員的名字。