powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Хитрая сортировка
9 сообщений из 34, страница 2 из 2
Хитрая сортировка
    #39357953
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadне сказано, что если текущий месяц - первый, и сравнивать за предыдущий нечего.не сказано - не сравнивай
no women - no cry
...
Рейтинг: 0 / 0
Хитрая сортировка
    #39357957
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--AmKadне сказано, что если текущий месяц - первый, и сравнивать за предыдущий нечего.не сказано - не сравнивайЕсли посмотришь мой запрос, то я и не сравниваю. И по этому поводу был вопрос от mraks-а.
...
Рейтинг: 0 / 0
Хитрая сортировка
    #39357967
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad,

да, извини
вообще говоря, мой запрос - это твой, только без аналитики.
и есть мнение, что подход FIRST/LAST работает быстрее, чем ROW_NUMBER() или FIRST_VALUE() / LAST_VALUE() и т.п.
...
Рейтинг: 0 / 0
Хитрая сортировка
    #39357974
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--и есть мнение, что подход FIRST/LAST работает быстрее, чем ROW_NUMBER() или FIRST_VALUE() / LAST_VALUE() и т.п.У меня в целом такое же ощущение. Хотя специально не проверял.
...
Рейтинг: 0 / 0
Хитрая сортировка
    #39358102
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Магия данных - еcли ничья, то выбирать победителя в предыдущем месяце надо не из вcех а только из претендентов:

Код: 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.
WITH Tab AS (
        SELECT 'A' AS Client, 'Q' AS Payer, 1 AS Pay_Month, 10 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'A' AS Client, 'W' AS Payer, 1 AS Pay_Month, 15 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'A' AS Client, 'X' AS Payer, 2 AS Pay_Month, 25 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'A' AS Client, 'W' AS Payer, 2 AS Pay_Month, 20 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'A' AS Client, 'Q' AS Payer, 3 AS Pay_Month, 30 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'A' AS Client, 'W' AS Payer, 3 AS Pay_Month, 30 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'B' AS Client, 'R' AS Payer, 1 AS Pay_Month, 10 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'B' AS Client, 'R' AS Payer, 1 AS Pay_Month, 50 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'B' AS Client, 'E' AS Payer, 2 AS Pay_Month, 25 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'C' AS Client, 'T' AS Payer, 1 AS Pay_Month, 30 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'C' AS Client, 'Y' AS Payer, 1 AS Pay_Month, 60 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'C' AS Client, 'T' AS Payer, 3 AS Pay_Month, 40 AS Pay_Sum FROM Dual
        UNION ALL
        SELECT 'C' AS Client, 'Y' AS Payer, 3 AS Pay_Month, 40 AS Pay_Sum FROM Dual
    )
select client, max(payer) keep (dense_rank last order by pay_month) payer
from
   (select client, payer, pay_month, pay_sum,
    row_number()  over (partition by client, pay_month          order by pay_sum desc) dr,
    count     (*) over (partition by client, pay_month, pay_sum order by pay_sum     ) cnt
    from tab
   )
where dr = cnt and cnt = 1
group by client
/

C P
- -
A X -- а надо W
B E
C Y

SQL> 



SY.
...
Рейтинг: 0 / 0
Хитрая сортировка
    #39358127
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_hz_Т.е. получается рекурсивный алгоритм:
1. Ищем максимальное значение Pay_Sum за максимальный Pay_Month. Если оно одно, то значение Payer -- результат.
2. Если максимальное значение Pay_Sum несколько, то выполняем шаг 1 для Pay_Month - 1.


Аналитика + иерархия:

Код: 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.
with x as (
           select 'A' client, 'Q' payer,3 pay_month,30 pay_sum from dual union all
           select 'A', 'W', 3, 30 from dual union all
           select 'A', 'Q', 2, 20 from dual union all
           select 'A', 'W', 2, 20 from dual union all
           select 'A', 'W', 1, 15 from dual union all
           select 'A', 'Q', 1, 10 from dual union all
           select 'B', 'E', 2, 25 from dual union all
           select 'B', 'R', 1, 50 from dual union all
           select 'B', 'R', 1, 10 from dual union all
           select 'C', 'T', 3, 40 from dual union all
           select 'C', 'Y', 3, 40 from dual union all
           select 'C', 'Y', 1, 60 from dual union all
           select 'C', 'T', 1, 30 from dual
          ),
    t1 as (
           select  client,
                   payer,
                   -- у плательщиков последнего месяца с макcимальными суммами drnk = 1
                   dense_rank() over(partition by client order by pay_month desc,pay_sum desc) drnk 
             from  x
          ),
    t2 as (
           select  x.client,
                   x.payer,
                   x.pay_sum,
                   -- начнем с одногo (любого) из плательщиков последнего месяца с макcимальнoй суммoй (start_row = 1)
                   row_number() over(partition by x.client order by x.pay_month desc,x.pay_sum desc) start_row,
                   -- пронyмеруем месяца (не требуется если они всегда идут подряд)
                   dense_rank() over(partition by x.client order by x.pay_month desc) pay_month_rn,
                   -- смотрим есть ли  в данном месяце несколько плательщиков с макcимальными суммами (flag = 'tie')
                   case 
                     when pay_sum = lag(x.pay_sum) over(partition by x.client,x.pay_month order by x.pay_sum) then 'tie'
                     when pay_sum = lead(x.pay_sum) over(partition by x.client,x.pay_month order by x.pay_sum) then 'tie'
                   end flag,
                   -- выбираем одногo (любого) из плательщиков данного месяца с макcимальнoй суммoй (pay_month_max_pay_rn = 1)
                   row_number() over(partition by x.client,x.pay_month order by x.pay_sum desc) pay_month_max_pay_rn
             from  x,
                   t1
             where t1.client = x.client
               and t1.payer  = x.payer
               and t1.drnk   = 1
          )
select  client,
        payer
  from  t2
  where connect_by_isleaf = 1
  start with start_row = 1
  connect by prior flag           = 'tie'
         and client               = prior client
         and pay_month_rn         = prior pay_month_rn + 1
         and pay_month_max_pay_rn = 1
/

C P
- -
A W
B E
C Y

SQL> 



SY.
...
Рейтинг: 0 / 0
Хитрая сортировка
    #39358197
_hz_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mraksAmKad,
А еще, я, возможно неправильно понял условие, но на этих данных, запрос вернет E, а надо Q.
Хотя это условие можно уточнить: после того, как в максимальный день совпали суммы для двух payer мы будем сравнивать предыдущие дни только для них или для всех?
Какой результат должен получиться на примере ниже?

WITH Tab AS (
SELECT 'A' AS Client, 'Q' AS Payer, 1 AS Pay_Month, 10 AS Pay_Sum FROM Dual
UNION ALL
SELECT 'A' AS Client, 'E' AS Payer, 1 AS Pay_Month, 15 AS Pay_Sum FROM Dual
UNION ALL
SELECT 'A' AS Client, 'Q' AS Payer, 2 AS Pay_Month, 20 AS Pay_Sum FROM Dual
UNION ALL
SELECT 'A' AS Client, 'W' AS Payer, 2 AS Pay_Month, 20 AS Pay_Sum FROM Dual
)
select client, max(payer) keep (dense_rank last order by pay_month) payer
from
(select client, payer, pay_month, pay_sum,
row_number() over (partition by client, pay_month order by pay_sum desc) dr,
count (*) over (partition by client, pay_month, pay_sum order by pay_sum ) cnt
from tab
)
where dr = cnt and cnt = 1
group by client;
Да, надо Q

SYМагия данных - еcли ничья, то выбирать победителя в предыдущем месяце надо не из вcех а только из претендентов Именно так.
Спасибо. Надо потестить Ваш запрос на боевых данных.
...
Рейтинг: 0 / 0
Хитрая сортировка
    #39359057
kaldorey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYМагия данных - еcли ничья, то выбирать победителя в предыдущем месяце надо не из вcех а только из претендентов
Это не решит проблемы, если все победители в последнем месяце платили ему только в этот месяц, и в более ранний период их не найти.
...
Рейтинг: 0 / 0
Хитрая сортировка
    #39359119
_hz_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY, спасибо большое. То, что надо!

kaldoreySYМагия данных - еcли ничья, то выбирать победителя в предыдущем месяце надо не из вcех а только из претендентов
Это не решит проблемы, если все победители в последнем месяце платили ему только в этот месяц, и в более ранний период их не найти.
Тогда любого.
...
Рейтинг: 0 / 0
9 сообщений из 34, страница 2 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Хитрая сортировка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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