PARTITION BY
セットを分離します。これにより、関連するセットで独立して作業(ROW_NUMBER()、COUNT()、SUM()など)できるようになります。
クエリでは、関連するセットは、類似したcdt.country_code、cdt.account、cdt.currencyの行で構成されています。それらの列を分割し、それらにROW_NUMBERを適用する場合。それらの組み合わせ/セットの他の列は、ROW_NUMBER
から連番を受け取ります。
しかし、そのクエリはおかしいです。いくつかの一意のデータによるパーティションで、row_numberをその上に置くと、同じ番号が生成されます。これは、一意であることが保証されているパーティションでORDERBYを実行するようなものです。たとえば、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 on OVERでは、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の組み合わせが見えますか?最初の3行は一意の組み合わせであるため、1に設定され、B行のWは同じであるため、HIC行と同様にROW_NUMBERSが異なります。
では、なぜORDER BY
なのですか? そこに必要ですか?前の開発者が単に類似したデータにrow_numberを配置したい場合(たとえば、HI B、すべてのデータはB-W、B-W)、彼はこれを行うことができます:
select
hi,ho,
row_number() over(partition by hi,ho)
from tbl;
しかし、残念ながら、Oracle(およびSQL Serverも)はORDER BY
のないパーティションを許可していません;一方、Postgresqlでは、ORDER BY
on PARTITIONはオプションです:http://www.sqlfiddle.com/#!1/27821/1
select
hi,ho,
row_number() over(partition by hi,ho)
from tbl;
ORDER BY
以前の開発者のせいではなく、パーティション上で少し冗長に見えます。一部のデータベースでは、PARTITION
が許可されていません。 ORDER BY
なし 、並べ替えるのに適した候補列が見つからない可能性があります。 PARTITIONBY列とORDERBY列の両方が同じである場合は、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を使用できます(newid()
を使用します SQL Serverの場合)。以前の開発者による出力と同じであるため、一部のデータベースでPARTITION
が許可されていないのは残念です。 ORDER BY
なし
本当に、それは私にはわかりません、そして私は同じ組み合わせ(上記の例ではB-W、B-W)に番号を付ける正当な理由を見つけることができません。データベースに冗長なデータがあるような印象を与えます。どういうわけか私にこれを思い出させました:テーブルからのレコードの同じリストから1つのユニークなレコードを取得する方法は?テーブルに一意性制約はありません
ORDERBYと同じ列の組み合わせを持つPARTITIONBYを見ると、本当に難解に見えますが、コードの意図を簡単に推測することはできません。
ライブテスト: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');
次に、こんにちは、hoでパーティションを作成します。それからあなたはこんにちは、hoで注文します。同様のデータに番号を付ける意味はありません:-)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で何を分析しますか? :-)
一意でない列でPARTITIONを使用するだけで、一意でない列の一意ので並べ替えることができます。 -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
これは、PARTITIONBYとORDERBYの両方に同じ列があるクエリに似ています:
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