powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / красивее найти максимум по двум полям
22 сообщений из 22, страница 1 из 1
красивее найти максимум по двум полям
    #39822513
Sintetik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть таблица с тремя столбцами
HASHIDSEQUENCE_NUMBERfile_name aaa1a1.csvaaa2a1.csvaaa3a1.csvaaa1a2.csvbbb1a1.csvbbb2a1.csvbbb1a1.csvbbb2a3.csv

искомый результат, для каждого кода нужно найти максимальную комбинацию SEQUENCE_NUMBER,file_name
причем file_name старше, т.е. для каждого кода найти максимальный файл в котором он встречается,
а в нем найти максимальный SEQUENCE_NUMBER
HASHIDSEQUENCE_NUMBERfile_name aaa 1 a2.csvbbb 2 a3.csv

можно ли сделать элегантнее?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select * from (
select HASHID, 
       file_name,
       max(SEQUENCE_NUMBER) OVER (PARTITION BY HASHID, file_name) as max_sq,
       ROW_NUMBER() OVER (PARTITION BY HASHID ORDER BY file_name DESC) as rn
    from  base_data
   )hh
where rn=1
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39822514
Sintetik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сортировка по имени файла условная, в реальной задаче там идет парсинг имени, но для упрощения считаем что сортировка стрики дает нужный результат для поиска максимального значения
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39822515
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Sintetik,

самая обычная группировка:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',1,'a1.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual union all
   select 'aaa',3,'a1.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a1.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual 
)
select hashid
      ,max(sequence_number)keep(dense_rank first order by file_name desc, sequence_number desc) as max_sequence_number
      ,max(file_name      )keep(dense_rank first order by file_name desc, sequence_number desc) as max_file_name
from base_data
group by hashid;
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823377
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',1,'a1.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual union all
   select 'aaa',3,'a1.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a1.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual 
)
select  hashid
      , sequence_number 
      , file_name 
from base_data
WHERE (hashid, file_name||'~'||sequence_number) IN 
         (SELECT hashid, MAX(file_name||'~'||sequence_number) 
          FROM base_data GROUP BY hashid)
order by hashid;
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823446
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL*Plus,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',1,'a1.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual union all
   select 'aaa',3,'a1.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a1.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual 
)
select  DISTINCT hashid
      , sequence_number 
      , file_name 
from base_data
WHERE (hashid, file_name||'~'||sequence_number) IN 
         (SELECT hashid, MAX(file_name||'~'||sequence_number) 
          FROM base_data GROUP BY hashid)
order by hashid;



SY.
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823455
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или через аналитику:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',1,'a1.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual union all
   select 'aaa',3,'a1.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a1.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual
),
x as (
SELECT hashid,file_name,sequence_number,
       row_number() over(partition by hashid order by file_name desc,sequence_number desc) rn
FROM base_data)
SELECT hashid,file_name,sequence_number
FROM x
WHERE rn = 1
ORDER BY hashid
/



SY.
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823461
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',1,'a1.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual union all
   select 'aaa',3,'a1.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a1.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual
)
select  DISTINCT hashid
      , sequence_number
      , file_name
from base_data
WHERE (hashid,file_name,sequence_number,1) IN
         (SELECT hashid,file_name,sequence_number,
                 row_number() over(partition by hashid order by file_name desc,sequence_number desc) rn
          FROM base_data)
order by hashid
/


:-)
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823465
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL*Plus,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',1,'a1.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual union all
   select 'aaa',3,'a1.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a1.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual
),
x as (
SELECT hashid,file_name,sequence_number,
       row_number() over(partition by hashid order by file_name desc,sequence_number desc) rn
FROM base_data)
SELECT hashid,file_name,sequence_number
FROM x
WHERE rn = 1
ORDER BY hashid
/



SY.
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823472
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYSQL*Plus,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',1,'a1.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual union all
   select 'aaa',3,'a1.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a1.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual
),
x as (
SELECT hashid,file_name,sequence_number,
       row_number() over(partition by hashid order by file_name desc,sequence_number desc) rn
FROM base_data)
SELECT hashid,file_name,sequence_number
FROM x
WHERE rn = 1
ORDER BY hashid
/



SY.Да.
Вижу, что вы тоже быстро обнаружили свою неточность и исправили запрос... :-)
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823492
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
группировка через аналитику? ....
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823507
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderгруппировка через аналитику? ....

А в чем проблема? И чем KEEP не аналитика по DENSE_RANK + фильтр FIRST/LAST?

SY.
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823517
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL*Plus,
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
SQL> ed
Wrote file afiedt.buf

  1  with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
  2     select 'aaa',1,'a2.csv.txt' from dual union all
  3     select 'aaa',2,'a1.csv' from dual union all
  4     select 'aaa',3,'a1.csv' from dual union all
  5     select 'aaa',1,'a2.csv' from dual union all
  6     select 'bbb',1,'a1.csv' from dual union all
  7     select 'bbb',2,'a1.csv' from dual union all
  8     select 'bbb',1,'a1.csv' from dual union all
  9     select 'bbb',2,'a3.csv' from dual
 10  )
 11  /*
 12  select  hashid
 13        , sequence_number
 14        , file_name
 15  from base_data
 16  WHERE (hashid, file_name||'~'||sequence_number) IN
 17           (SELECT hashid, MAX(file_name||'~'||sequence_number)
 18            FROM base_data GROUP BY hashid)
 19  order by hashid
 20  */
 21  select * from (
 22  select HASHID,
 23         file_name,
 24         max(SEQUENCE_NUMBER) OVER (PARTITION BY HASHID, file_name) as max_sq,
 25         ROW_NUMBER() OVER (PARTITION BY HASHID ORDER BY file_name DESC) as rn
 26      from  base_data
 27     )hh
 28* where rn=1
SQL> /

HAS FILE_NAME      MAX_SQ         RN
--- ---------- ---------- ----------
aaa a2.csv.txt          1          1
bbb a3.csv              2          1

SQL> ed
Wrote file afiedt.buf

  1  with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
  2     select 'aaa',1,'a2.csv.txt' from dual union all
  3     select 'aaa',2,'a1.csv' from dual union all
  4     select 'aaa',3,'a1.csv' from dual union all
  5     select 'aaa',1,'a2.csv' from dual union all
  6     select 'bbb',1,'a1.csv' from dual union all
  7     select 'bbb',2,'a1.csv' from dual union all
  8     select 'bbb',1,'a1.csv' from dual union all
  9     select 'bbb',2,'a3.csv' from dual
 10  )
 11  select  hashid
 12        , sequence_number
 13        , file_name
 14  from base_data
 15  WHERE (hashid, file_name||'~'||sequence_number) IN
 16           (SELECT hashid, MAX(file_name||'~'||sequence_number)
 17            FROM base_data GROUP BY hashid)
 18* order by hashid
 19  /

HAS SEQUENCE_NUMBER FILE_NAME
--- --------------- ----------
aaa               1 a2.csv
bbb               2 a3.csv

SQL>



....
stax
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823544
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

Тут и проблема с числами:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',10,'a1.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual
)
select  hashid
      , sequence_number
      , file_name
from base_data
WHERE (hashid, file_name||'~'||sequence_number) IN
         (SELECT hashid, MAX(file_name||'~'||sequence_number)
          FROM base_data GROUP BY hashid)
order by hashid
/

HAS SEQUENCE_NUMBER FILE_N
--- --------------- ------
aaa               2 a1.csv

SQL> 



Числа надо "выравнивать":

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',10,'a1.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual
)
select  hashid
      , sequence_number
      , file_name
from base_data
WHERE (hashid, file_name||'~'||to_char(sequence_number,'9999999999')) IN
         (SELECT hashid, MAX(file_name||'~'||to_char(sequence_number,'9999999999'))
          FROM base_data GROUP BY hashid)
order by hashid
/

HAS SEQUENCE_NUMBER FILE_N
--- --------------- ------
aaa              10 a1.csv

SQL> 



А '~' использовать нельзя (как ты и показал). Использовать надо CHR(0):

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',1,'a2.csv.txt' from dual union all
   select 'aaa',2,'a1.csv' from dual union all
   select 'aaa',3,'a1.csv' from dual union all
   select 'aaa',1,'a2.csv' from dual union all
   select 'bbb',1,'a1.csv' from dual union all
   select 'bbb',2,'a1.csv' from dual union all
   select 'bbb',10,'a3.csv' from dual union all
   select 'bbb',2,'a3.csv' from dual
)
select  DISTINCT hashid
      , sequence_number
      , file_name
from base_data
WHERE (hashid, file_name||chr(0)||to_char(sequence_number,'9999999999')) IN
         (SELECT hashid, MAX(file_name||chr(0)||to_char(sequence_number,'9999999999'))
          FROM base_data GROUP BY hashid)
order by hashid
/

HAS SEQUENCE_NUMBER FILE_NAME
--- --------------- ----------
aaa               1 a2.csv.txt
bbb              10 a3.csv

SQL> 



SY.
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823565
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYИспользовать надо CHR(0)
Однажды наткнулся на клиента, в данных которого таки был chr(0) - имеет смысл проявлять некоторую осторожность :)
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823580
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousОднажды наткнулся на клиента, в данных которого таки был chr(0) - имеет смысл проявлять некоторую осторожность :)

В принципе - да, но в имeни файла вроде как нет :).

SY.
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823602
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SYxtenderгруппировка через аналитику? ....

А в чем проблема? И чем KEEP не аналитика по DENSE_RANK + фильтр FIRST/LAST?

SY.абсолютно разные алгоритмы, функции и выделение памяти - сравни планы
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823620
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не все так однозначно...
SYЧисла надо "выравнивать":
Код: plsql
1.
2.
3.
4.
5.
6.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',10,'a1.csv' from dual union all
   select 'aaa',9,'a2.csv' from dual union all
   select 'aaa',8,'a10.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual
)
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823623
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderабсолютно разные алгоритмы

не могу догадатся почему ,max(file_name )keep(dense_rank first order by file_name desc, sequence_number desc) as max_file_name

простого max(file_name ) недостаточно?

.....
stax
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823626
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousНе все так однозначно...
SYЧисла надо "выравнивать":
Код: plsql
1.
2.
3.
4.
5.
6.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',10,'a1.csv' from dual union all
   select 'aaa',9,'a2.csv' from dual union all
   select 'aaa',8,'a10.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual
)


в чем подвох (если считать что 21901900 отрабатывает правильно)?

....
stax
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823627
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderабсолютно разные алгоритмы, функции и выделение памяти - сравни планы

Имплементация разная - логика примерно та-же. Что GROUP BY, что PARTITION BY разбивают set на группы и вычисляют DENSE_RANK (GROUP BY) или ROW_NUMBER (аналитикa c ORDER BY для FIRST или ORDER BY DESC для LAST). Дальше GROUP BY берет строки (а их может быть > 1) с FIRST или LAST DENSE_RANK и аггрегирует. С аналитикой мы делаем то-же через in-lion view/with clause фильтруя по ROW_NUMBER = 1.

SY.
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823637
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Staxв чем подвох (если считать что 21901900 отрабатывает правильно)?

stax

Андрей о том что a10.csv должен быть > a2.csv. Hо это другая проблема. Если сравнивать надо как alphanumeric то это решается например регуляркой. Скажем numeric порции <= 10 цифр:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
with base_data(HASHID,SEQUENCE_NUMBER,file_name) as (
   select 'aaa',10,'a1.csv' from dual union all
   select 'aaa',9,'a2.csv' from dual union all
   select 'aaa',8,'a10.csv' from dual union all
   select 'aaa',2,'a1.csv' from dual
),
x as (
SELECT hashid,file_name,sequence_number,
       row_number() over(
                         partition by hashid
                         order by regexp_replace(
                                                 regexp_replace(
                                                                file_name,
                                                                '(\d+)',
                                                                '000000000\1'
                                                               ),
                                                '\d*(\d{10})',
                                                '\1'
                                                ) desc,
                                  sequence_number desc
                        ) rn
FROM base_data)
SELECT hashid,file_name,sequence_number
FROM x
WHERE rn = 1
ORDER BY hashid
/

HAS FILE_NA SEQUENCE_NUMBER
--- ------- ---------------
aaa a10.csv               8

SQL> 



SY.
...
Рейтинг: 0 / 0
красивее найти максимум по двум полям
    #39823667
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYИмплементация разная - логика примерно та-же.
Аналитика по сути должна формировать (и часто материализовать в temp) весь rowset, который лишь на следующем шаге плана будет почитан (в т.ч. из temp), отфильтрован, агрегирован.
Агрегация же зачастую может себе позволить инкрементально копить агрегаты прямо из потока базового rowsource, что снижает требования к памяти и ресурсам на промежуточных шагах плана.
По этой причине лично я избегаю применения аналитики там, где достаточно агрегации.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / красивее найти максимум по двум полям
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]