powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / как хинтами добиться нужного плана
13 сообщений из 38, страница 2 из 2
как хинтами добиться нужного плана
    #39578077
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadРавенства по номеру счета должно хватить.С удовольствием посмотрю на твое решение, учитывая что для одного счета может быть дохрена записей 4 и 5 из cum_money_in_out_hist
niv76
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
 select ct1.dc_type_id, count(1)
  from client c1, cum_money_in_out_hist ct1, account a
 where c1.account_number = a.account_number
   and ct1.client_id = c1.client_id
   and ct1.dc_type_id IN (4,5)                   
   and a.account_id = 1 
group by ct1.dc_type_id
;

получил:
4	31004
5	30940

данный немного поменялись со вчерашнего дня...

и их необходимо схлопнуть учитывая условие для self join
Код: plsql
1.
2.
3.
            on t1.rc_cl_trade_id = t2.cl_trade_id
           and t1.client_id <> t2.client_id
           and t1.balance_currency <> t2.balance_currency

Можно обойтись без джойна с помощью model, но это баловство.
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578083
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopучитывая что для одного счета может быть дохрена записей 4 и 5 из cum_money_in_out_histНу вот чтобы не гадать, пусть автор дает данные, обладающие свойствами реальных. И посмотрим, что можно с ними сделать. Правда я оперативность ответа не гарантирую, не знаю когда до оракла доберусь.
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578092
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad,

Автор получив ответы на свои вполне может потерять интерес к теме.
Я до Оракла доберусь в 2018, но могу дать заготовку.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
with
client(client_id, account_number, balance_currency)
as (select 1,1,'USD' from dual union all select 2,1,'GBP' from dual)
,
cum_money_in_out_hist(client_id, dc_type_id, cl_trade_id, rc_cl_trade_id,settlement_id)
as (select 1,4,0,0,1 from dual union all select 2,5,0,0,1 from dual)
select *
  from client c1, cum_money_in_out_hist ct1, account a
 where c1.account_number = a.account_number
   and ct1.client_id = c1.client_id
   and ct1.dc_type_id IN (4,5)                   
   and a.account_id = 1

Думаю, очевидно, что не стоит заклыдваться что здесь по одной строке на 4 и 5.
Я не тороплю. :))
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578139
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopДумаю, очевидно, что не стоит заклыдваться что здесь по одной строке на 4 и 5.

А если предположить, что trade_id суть идентификатор сделки, при этом интересуют только сделки, содержащие ровно по одному участнику на каждой из сторон?
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578220
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

Да там мутняк отчасти, то что я вижу это сделки в приделах одного счета.
Но сделка должна быть между разными клиентами и разными валютами, что, по моему, делаеться только через SWIFT в Украине.
Но вот что удивляет, что ищут MAX(settlement_id) могу только предполагать что это идентификатор валютных операций и если нет конвертации он равен 0 например. Посему мне кажеться что это и есть достаточный признак для того чтоб сказать что была конвертация. А то что не через себя (c1.client_id <> c2.client_id), можно проверить и по другому т.к. client_id - primary key.

В общем очень бы хотелось увидеть пример от автора, не обязательно много (сотни) клиентов, на 2-х, 3-х все будет понятно. Потому как у меня не очень сходится если на один счет (a.account_id = 1) будет 3 клиента со сделками ct1.dc_type_id = 4 какой информативности будет единый результат MAX(settlement_id) ... это говорит или об утере данных о 2 сделках клиентов, или что с ct1.dc_type_id = 4 может быть только 1 клиент, или еще хз что. Но постановка/пример хотелось бы увидеть, а то как в хрустальный шар.
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578659
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за ответы.
Поспрашивал немного насчет физического смысла запроса. По сути account_number, я так понял, идетнифицирует одного клиента банка. Client_id - это ид счета в разной валюте. две строки ( ct2.dc_type_id = 4 (transfer from) и ct2.dc_type_id = 5 (transfer to) ) фактически это операция конвертации с одной валюты в другую. Settlement_id - это фактически дата банковского дня.
Соответственно строк ct2.dc_type_id = 5 , ct2.dc_type_id = 4 может быть много и не всегда между разными валютами, но всегда между разными client_id. Фактически фильтр на неравенство client_id - избыточный.
Попробую сегодня сделать немного репрезентавивных тестовых данных....
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578660
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Но фильтр на не равенство валют, актуальный:

c1.balance_currency <> c2.balance_currency
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578687
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
niv76,

Можно так попробовать, если я не запутался =)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select max(prior ct1.settlement_id)
  from client c1, cum_money_in_out_hist ct1
 where c1.account_number = 1 /*account_number*/  
   and ct1.client_id = c1.client_id  
   and ct1.dc_type_id IN (4,5)                    
   and level = 2
   START WITH ct1.dc_type_id = 4 
   connect by nocycle prior ct1.rc_cl_trade_id = ct1.cl_trade_id and prior c1.balance_currency != c1.balance_currency and prior ct1.client_id != ct1.client_id



Т.к. без данных можно только прикидывать
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578701
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXL,

надо еще дописать в конце
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select max(prior ct1.settlement_id)
  from client c1, cum_money_in_out_hist ct1
 where c1.account_number = 1 /*account_number*/  
   and ct1.client_id = c1.client_id  
   and ct1.dc_type_id IN (4,5)                    
   and level = 2
   START WITH ct1.dc_type_id = 4 
   connect by nocycle prior ct1.rc_cl_trade_id = ct1.cl_trade_id and prior c1.balance_currency != c1.balance_currency and prior ct1.client_id != ct1.client_id and ct1.dc_type_id = 5

... а то может случиться ссылка ct1.dc_type_id = 4 на ct1.dc_type_id = 4.
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578708
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cl_trade_id ПК транзакции. rc_cl_trade_id - ссылка на связанную парную транзакцию.
Транзакции dc_type_id in (4,5) могут быль либо одиночными (если деньги заводяться или выводятся из системы). Для таких строк rc_cl_trade_id = NULL. Либо парными - когда деньги перебрасываются в системе между разными счетами (rc_cl_trade_id IS NOT NULL).

Скрипт с данными в файле.

Код: 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.
select a.account_number,
               (select  MAX(ct1.settlement_id)
                from  client c1,
                      cum_money_in_out_hist ct1,
                      client c2,
                      cum_money_in_out_hist ct2                     
                where c1.account_number = a.account_number
                  and ct1.client_id = c1.client_id
                  and ct1.dc_type_id = 4
                  and c2.account_number = a.account_number
                  and c2.client_id      = ct2.client_id 
                  and ct2.dc_type_id    = 5                  
                  and ct1.rc_cl_trade_id = ct2.cl_trade_id
                  and c1.client_id <> c2.client_id 
                  and c1.balance_currency <> c2.balance_currency
                  ) LAST_EXCHANGE
          from account a
order by 1          
;

account_number, last_exchange
1000067	20170623
1000097	
1000103	
1011408	20170710
5050005	20171229
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578711
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
niv76,

21078527
Вернул Ваш результат
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578715
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Остался спортивный интерес сделать с группировкой и проверкой c1.balance_currency <> c2.balance_currency, не делая второго джойна ( client c2, cum_money_in_out_hist ct2 )
Похоже даже у самого получилось, может кто-то красивее может:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
select a.account_number,
               (select  max(MAX(decode(dc_type_id,4,ct1.settlement_id)))
                from  client c1,
                      cum_money_in_out_hist ct1
                where c1.account_number = a.account_number
                  and ct1.client_id = c1.client_id
                  and ct1.dc_type_id in (4,5) and
                  ct1.rc_cl_trade_id is not null
                group by decode(ct1.dc_type_id, 4, ct1.cl_trade_id, 5, ct1.rc_cl_trade_id)
                having count(distinct c1.balance_currency) = 2
                  ) LAST_EXCHANGE
          from account a
order by 1 
...
Рейтинг: 0 / 0
как хинтами добиться нужного плана
    #39578716
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MaximaXXL,

да, спасибо. Вариант рабочий.
...
Рейтинг: 0 / 0
13 сообщений из 38, страница 2 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / как хинтами добиться нужного плана
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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