邪悪なコーディングが戻ってきたとき、私たちは嫌いではありませんか?
少し前に、後でさらに処理するために、いくつかのフィールドを連結する文字列を生成する必要がありました。クエリを直接実行するのは良い考えだと思い、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
私は実際にこれをあまりレコードがない多くの場所で使用しています。約50万レコードまではかなり問題ありません。
最近、私は〜15Miのレコードを持つテーブルで同じことを試しましたが、まあ...ダメです。
質問:これをOracleでより効率的に行う方法はありますか、それとも実際のコードに落とし込むときですか?これは実際の主要な問題ではないので、高速である限り、まだクラッジングを行う余裕があります...私が使用している「usrid」列のインデックスがあることは言及する価値があります。
乾杯、