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 на OVER необходимо ограждающей 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
Вы видите thee комбинацию 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;
Но увы, Oracle (и Sql Server тоже) Безразлично разрешить перегородку без ORDER BY
; в то время как в Postgresql, ORDER BY
на 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
, он мог бы не удалось найти хороший столбец кандидатов для сортировки. Если оба 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 (вы используете newid()
для SQL Server). Так что имеет тот же вывод, сделанный предыдущим разработчиком, это прискорбно, что некоторые базы данных не позволяет 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');
Тогда вы PARTITION BY привет, хо; и тогда вы ЗАКАЗЫВАЕТ привет, хо. Там нет смысла нумерации подобные данные :-) 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 на неуникальном колонке, то сортировать по неуникальному колонку (ов) 's уникального -ный колонка.Пример сделает его более ясным:
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
работает на не уникальном столбце, а затем на каждую секционированную колонке, заказ на своей уникальной колонке (хо), 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;
И это Ouput:
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