應用場景:假設一張存放了商品名稱及**的表,表裡有「蘋果、橘子、香蕉」三條記錄。在生成用於查詢銷售額的報表時,需要獲取這些商品的組合。
組合:分為有順序的有序對 <1,2> 和 無順序的無序對 。分別對應「排列」和「組合」
(1)可重排列
通過交叉連線生成笛卡爾積,可以得到有序對
/* 用於獲取可重排列的sql語句 */
select p1.name as name_1, p2.name as name_2
from products p1, products p2;
(2)排列
去掉由相同元素構成的對。
/* 用於獲取排列的sql語句 */
select p1.name as name_1, p2.name as name_2
from products p1, products p2
where p1.name <> p2.name;
(3)組合
對調換了元素順序的對進行去重
/* 用於獲取組合的sql語句 */
select p1.name as name_1, p2.name as name_2
from products p1, products p2
where p1.name > p2.name;
若想要獲取3個以上元素的組合,只需要簡單擴充套件一下即可
/* 用於獲取組合的sql語句:擴充套件成3列時 */
select p1.name as name_1, p2.name as name_2, p3.name as name_3
from products p1, products p2, products p3
where p1.name > p2.name
and p2.name > p3.name;
(1)使用極值函式
/* 用於刪除重複行的sql語句(1):使用極值函式 */
delete from products p1
where rowid < ( select max(p2.rowid)
from products p2
where p1.name = p2. name
and p1.price = p2.price )
sql中賦予不同名稱的集合,我們應該將其看作不同的集合,這個子查詢會比較p1、p2,然後返回商品名稱和**都相同的行裡最大的rowid所在的行。
(2)使用非等值連線
/* 用於刪除重複行的sql語句(2):使用非等值連線 */
delete from products p1
where exists ( select *
from products p2
where p1.name = p2.name
and p1.price = p2.price
and p1.rowid < p2.rowid );
場景:查詢「同一家人但是住址不同的記錄」
自連線與非等值連線結合
/* 用於查詢是同一家人但住址卻不同的記錄的sql語句 */
select distinct a1.name, a1.address
from addresses a1, addresses a2
where a1.family_id = a2.family_id
and a1.address <> a2.address ;
問題:查詢**相等的商品組合
思路:家庭——>**
住址——>商品名稱
應用場景:在使用資料庫製作各種票據和統計表工作中,會經常遇到按分數、人數或者銷售額等數值進行排序的需求。(oracle 、db2 資料庫的rank函式)
(1)使用視窗函式
/* 排序:使用視窗函式 */
select name, price,
rank() over (order by price desc) as rank_1,
dense_rank() over (order by price desc) as rank_2
from products;
出現相同位次後,rank_1跳過之後的位次,rank_2沒有跳過,而是連續排序。
(2)sql 和 集合論的關係
/* 排序從1開始。如果已出現相同位次,則跳過之後的位次 */
select p1.name,
p1.price,
(select count(p2.price)
from products p2
where p2.price > p1.price) + 1 as rank_1
from products p1
order by rank_1;
/* 排序從1開始,連續輸出位次 */
select p1.name,
p1.price,
(select count( distinct p2.price)
from products p2
where p2.price > p1.price) + 1 as rank_1
from products p1
order by rank_1;
執行原理:面向集合的思維方式。子查詢所做的,是計算出**比自己高的記錄並將其作為自己的位次。
集合**
比自己高的**
位次s0
1000
s180
1001
s150
100,802s2
30100,80,50
30=空
1=2=
3=(3)使用自連線
/* 排序:使用自連線 */
select p1.name,
max(p1.price) as price,
count(p2.name) +1 as rank_1
from products p1 left outer join products p2
on p1.price < p2.price
group by p1.name
order by rank_1;
MySQL系列之自連線用法簡介
mysql系列之自連線簡介,mysql自連線操作,沒有特定的關鍵字,所謂自連線指的是同乙個表不同例項之間的join操作 引用的圖示 特徵 自連線操作一般應用與有層級關係的表,最經典的就是員工 經理例子 ok,下面舉例說明 建立部門dept表 table structure for table dep...
mysql自連線例項 Mysql自連線查詢例項詳解
自連線查詢 假想以下場景 某一電商 想要對站內產品做層級分類,乙個類別下面有若干子類,子類下面也會有別的子類。例如數碼產品這個類別下面有筆記本,台式電腦,智慧型手機等 筆記本,台式電腦,智慧型手機又可以按照品牌分類 品牌又可以按照 分類,等等。也許這些分類會達到乙個很深的層次,呈現一種樹狀的結構。那...
mysql自連線查詢 Mysql自連線查詢例項詳解
自連線查詢 假想以下場景 某一電商 想要對站內產品做層級分類,乙個類別下面有若干子類,子類下面也會有別的子類。例如數碼產品這個類別下面有筆記本,台式電腦,智慧型手機等 筆記本,台式電腦,智慧型手機又可以按照品牌分類 品牌又可以按照 分類,等等。也許這些分類會達到乙個很深的層次,呈現一種樹狀的結構。那...