PARTITION BY
隔離套,這使你能夠工作(ROW_NUMBER(),COUNT(),SUM()等),對相關獨立設置。
在您的查詢中,相關集由具有類似cdt.country_code,cdt.account,cdt.currency的行組成。當你在這些列上進行分區時,你會對它們應用ROW_NUMBER。這些組合/集合上的其他列將從ROW_NUMBER接收序列號
但是,該查詢很有趣,如果您的分區由一些獨特的數據組成,並且您將一個row_number放在它上面,它只會產生相同的數字。這就像你在一個保證唯一的分區上做ORDER BY一樣。例如,將GUID看作是cdt.country_code, cdt.account, cdt.currency
newid()
的唯一組合產生GUID,那麼您希望通過該表達式得到什麼結果?
select
hi,ho,
row_number() over(partition by newid() order by hi,ho)
from tbl;
...對,所有的分區(沒有進行分配,每一行是在自己的行分區)行row_numbers都設置爲1
基本上,你應該對非唯一分區列。 ORDER BY超過所需的PARTITION BY有一個非唯一的組合,否則所有row_numbers將成爲1
一個例子,這是你的數據:
create table tbl(hi varchar, ho varchar);
insert into tbl values
('A','X'),
('A','Y'),
('A','Z'),
('B','W'),
('B','W'),
('C','L'),
('C','L');
然後,這是類似於查詢:
select
hi,ho,
row_number() over(partition by hi,ho order by hi,ho)
from tbl;
那會是什麼輸出?
HI HO COLUMN_2
A X 1
A Y 1
A Z 1
B W 1
B W 2
C L 1
C L 2
你看到HI HO的組合嗎?前三行具有獨特的組合,因此它們被設置爲1,B行具有相同的W,因此具有不同的ROW_NUMBERS,與HI C行同樣。
現在,爲什麼ORDER BY
需要那裏?如果以前開發商只是希望把類似的數據ROW_NUMBER(如HI B,所有的數據都BW,BW),他只是這樣做:
select
hi,ho,
row_number() over(partition by hi,ho)
from tbl;
但很可惜,甲骨文(和SQL Server太)沒有按不允許分區沒有ORDER BY
;而在PostgreSQL,ORDER BY
上分區是可選的:http://www.sqlfiddle.com/#!1/27821/1
select
hi,ho,
row_number() over(partition by hi,ho)
from tbl;
你ORDER BY
你的分區看起來有些多餘,不是因爲以前開發商的過錯,有些數據庫只是不允許PARTITION
沒有ORDER BY
,他可能無法找到合適的候選人專欄進行排序。如果兩個PARTITION BY列和ORDER BY列是相同的只是刪除了ORDER BY,但由於一些數據庫不允許它,你可以這樣做:
SELECT cdt.*,
ROW_NUMBER()
OVER (PARTITION BY cdt.country_code, cdt.account, cdt.currency
ORDER BY newid())
seq_no
FROM CUSTOMER_DETAILS cdt
你不能找到一個很好的列使用整理類似的數據?你也可以隨機排序,分區數據總是有相同的值。例如,您可以使用GUID(對SQL Server使用newid()
)。因此,具有由以前的開發取得了相同的輸出,這是不幸的是,某些數據庫不允許PARTITION
沒有ORDER BY
但實際上,它躲開我,我不能找到一個很好的理由對同一組合的數字( BW,BW在上面的例子中)。它給人以數據庫有冗餘數據的印象。不知何故,我想起了這個:How to get one unique record from the same list of records from table? No Unique constraint in the table
它真的看起來神祕,看到一個PARTITION BY與ORDER BY列相同的組合,不能輕易推斷出代碼的意圖。
現場測試:http://www.sqlfiddle.com/#!3/27821/6
但作爲dbaseman也注意到,這是沒用的分區,在同一列的順序。
你有這樣一組數據:
create table tbl(hi varchar, ho varchar);
insert into tbl values
('A','X'),
('A','X'),
('A','X'),
('B','Y'),
('B','Y'),
('C','Z'),
('C','Z');
然後你分區中喜,豪;然後你訂購嗨,嗨。毫無意義的編號類似的數據:-) http://www.sqlfiddle.com/#!3/29ab8/3
select
hi,ho,
row_number() over(partition by hi,ho order by hi,ho) as nr
from tbl;
輸出:
HI HO ROW_QUERY_A
A X 1
A X 2
A X 3
B Y 1
B Y 2
C Z 1
C Z 2
看到了嗎?爲什麼需要將行號放在同一個組合上?你將分析三重A,X,雙B,Y,雙C,Z? :-)
你只需要在非唯一列中使用分區,那麼您排序非唯一列(S)的獨特 -ing列。例如會更清楚:
create table tbl(hi varchar, ho varchar);
insert into tbl values
('A','D'),
('A','E'),
('A','F'),
('B','F'),
('B','E'),
('C','E'),
('C','D');
select
hi,ho,
row_number() over(partition by hi order by ho) as nr
from tbl;
PARTITION BY hi
運行在非唯一列,然後在每個分區列,你爲了其獨特的列(HO),ORDER BY ho
輸出:
HI HO NR
A D 1
A E 2
A F 3
B E 1
B F 2
C D 1
C E 2
該數據集更有意義
現場測試:http://www.sqlfiddle.com/#!3/d0b44/1
這類似於在同一列的查詢上都PARTITION BY和ORDER BY:
select
hi,ho,
row_number() over(partition by hi,ho order by hi,ho) as nr
from tbl;
這是輸出中:
HI HO NR
A D 1
A E 1
A F 1
B E 1
B F 1
C D 1
C E 1
看到了嗎?沒有意義?
現場測試:http://www.sqlfiddle.com/#!3/d0b44/3
最後,這可能是正確的查詢:
SELECT cdt.*,
ROW_NUMBER()
OVER (PARTITION BY cdt.country_code, cdt.account -- removed: cdt.currency
ORDER BY
-- removed: cdt.country_code, cdt.account,
cdt.currency) -- keep
seq_no
FROM CUSTOMER_DETAILS cdt