Разве мы не ненавидим, когда злое кодирование снова начинает преследовать?
Некоторое время назад мне нужно было сгенерировать строку, объединяющую некоторые поля для дальнейшей обработки позже. Я подумал, что это будет хорошей идеей, если прямо в запросе, и использовал помощь SO, чтобы получить его. Это сработало. Какое-то время ...
Стол стал большим, и теперь этот трюк (который, как я знаю, супер неэффективен) не совсем жизнеспособен. Вот что я делаю:
with my_tabe as
(
select 'user1' as usrid, '1' as prodcode from dual union
select 'user1' as usrid, '2' as prodcode from dual union
select 'user1' as usrid, '3' as prodcode from dual union
select 'user2' as usrid, '2' as prodcode from dual union
select 'user2' as usrid, '3' as prodcode from dual union
select 'user2' as usrid, '4' as prodcode from dual
)
select
usrid,
ltrim(sys_connect_by_path(prodcode, '|'), '|') as prodcode
from
(
select distinct prodcode, usrid,count(1)
over (partition by usrid) as cnt,
row_number() over (partition by usrid order by prodcode) as rn
from my_tabe
)
where
rn = cnt
start with rn = 1
connect by prior rn + 1 = rn
and prior usrid = usrid
Что приятно дает:
USRID PRODCODE
user1 1|2|3
user2 2|3|4
Зло здесь, как вы могли заметить, это where rn = cnt
, который, если вы удалите, вы увидите всю работу (я полагаю), которую Oracle действительно делает:
USRID PRODCODE
user1 1
user1 1|2
user1 1|2|3
user2 2
user2 2|3
user2 2|3|4
На самом деле я использую это во многих местах, где у меня не так много записей. Это вполне нормально, примерно до полумиллиона записей.
Недавно я попробовал то же самое в таблице с ~ 15Mi записями, и хорошо ... ничего хорошего.
Вопрос: есть ли способ сделать это более эффективно в Oracle или пришло время свести его к реальному коду?
Это не актуальная основная проблема, поэтому я все еще могу позволить себе путаться, пока это быстро ...
Стоит отметить, что для столбца «usrid» я использую индекс.
ура