Oracle 根據某個欄位對查詢結果去重 三種方法詳述
Oracle三種去重的方法
distinct
group by
rowid
分組函式:作用於一組資料,並對一組資料返回一個值
常見的分組函式有:
count
返回找到的記錄數
min
返回一個數字列或計算列的最小值
max
返回一個數字列或計算列的最大值
sum
返回一個數字列或計算列總和
avg
返回一個數字列或計算列的平均值
一、distinct
distinct 單列
select distinct(a) from tableA;
distinct 多列
--會報錯,distinct 必須放在 select 語句的最前方
select a, distinct b,c from tableA;
select distinct a,b,c from tableA;
多列的時候,上述語句是針對abc的組合來distinct的,列出的是abc的所有不同組合,相當於下列語句
select a,b,c from tableA group by a,b,c;
那麼,如果想要分別查詢a,b,c三個欄位的distinct值怎麼辦?一開始可能只想到下列三個語句
select distinct a from tableA;
select distinct b from tableA;
select distinct c from tableA;
麻煩,如何合併成一個語句呢,使用union
解決,後面拼接的字串是為了標識這個值屬於哪個欄位:
select distinct(a) || ' a' from tableA
union all
select distinct(b) || ' b' from tableA
union all
select distinct(c) || ' c' from tableA
二、group by
只查詢非分組函式,不需要使用group by
;
select Name, Gender from dba_data_files;
只要查詢了分組函式,就需要使用group by
:
- 只查詢分組函式的話,
group by
的子句裡用到的列名Name 和 Gender
,不需要寫在select
裡;但select
裡出現別的列就會報錯;
select sum(Age) from dba_data_files group by Name, Gender;
-- 但 select 裡出現別的列就會報錯,例:
select Weight, sum(Age) from dba_data_files group by Name, Gender;
- 同時查詢分組函式和非分組函式,並且必須將分組函式以外的所有的列(
Name 和 Gender
),都寫到group by裡,少一個都不行;
select Name, Gender, sum(Age) from dba_data_files group by Name, Gender;
不管select
是否使用了where
子句,都可以使用group by
子句
三、rowid
rowid簡介
rowid是一個用來唯一標記表中行的偽列。它是物理表中行資料的內部地址,包含兩個地址,其一為指向資料表中包含該行的塊所存放資料檔案的地址,另一個是可以直接定位到資料行自身的這一行在資料塊中的地址。
除了在同一聚簇中可能不唯一外,每條記錄的rowid是唯一的。可以理解成rowid就是唯一的。
rowid解析
從Oracle 8i開始使用擴充套件rowid標識行實體地址
擴充套件rowid使用base64編碼行的實體地址,編碼字元包含A-Z, a-z, 0-9, +, 和/。
擴充套件rowid由四部分組成:OOOOOOOFFFBBBBBBRRR:
rowid包含如下內容:
①:物件所在的資料檔案號
②:物件所在的塊號
③:物件所在行在塊內的位置
④:物件號
其中:
OOOOOO:資料物件編號(6位顯示)
FFF:相關資料檔案編號(3位顯示)
BBBBBB:資料塊編號(6位顯示)
RRR:資料塊中行編號(3位顯示)
rowid示例
利用rowid
結合max
和min
函式快速去重
select t.* from bill t where t.rowid = (select max(s.rowid) from bill s
where t.FLAG = s.FLAG
and s.btype = 1
and s.CODE in ('71131702422','71130427253','71134427859')
);
利用rowid
結合max
和min
函式快速刪除重複資料
-- 使用min函式的時候用大於號>
delete t.* from bill t where t.rowid < (select max(s.rowid) from bill s
where t.FLAG = s.FLAG
and s.btype = 1
and s.CODE in ('71131702422','71130427253','71134427859')
);
Mysql
裡,可以用Max
函式,類似於Oracle
的rowid
的max
;
SQL Server
中也有First_Value
和Last_Value
函式,可以用來實現。