这是我正在尝试做的和我得到的最小的工作示例:
我有一个查询如下:
- /*
- with tran_party as -- ALL DUMMY DATA ARE IN THESE CTE FOR YOUR REFERENCE
- (select 1 tran_party_id,11 transaction_id,101 team_id_redirect
- from dual
- union all
- select 2,11,101 from dual
- union all
- select 3,102 from dual
- union all
- select 4,12,103 from dual
- union all
- select 5,103 from dual
- union all
- select 6,104 from dual
- union all
- select 7,13,104 from dual
- union all
- select 8,105 from dual),tran as
- (select 11 transaction_id,1001 account_id,1034.93 amount from dual
- union all
- select 12,1001,2321.89 from dual
- union all
- select 13,1002,3201.47 from dual),account as
- (select 1001 account_id,111 team_id from dual
- union all
- select 1002,112 from dual),team as
- (select 101 team_id,'UUU' as team_code from dual
- union all
- select 102,'VV' from dual
- union all
- select 103,'WWW' from dual
- union all
- select 104,'XXXXX' from dual
- union all
- select 105,'Z' from dual)
- -- */
- -- The Actual Query
- select a.account_id,t.transaction_id,(select listagg (tm_redir.team_code,',')
- within group (order by tm_redir.team_code)
- from tran_party tp_redir
- inner join team tm_redir
- on tp_redir.team_id_redirect = tm_redir.team_id
- inner join tran t_redir
- on tp_redir.transaction_id = t_redir.transaction_id
- where t_redir.account_id = a.account_id
- and t_redir.transaction_id != t.transaction_id)
- as teams_redirected
- from tran t inner join account a on t.account_id = a.account_id;
NOTE: tran_party.team_id_redirect is a foreign key that references team.team_id.
当前输出:
- ACCOUNT_ID TRANSACTION_ID TEAMS_REDIRECTED
- ---------- -------------- ----------------
- 1001 11 WWW,WWW,XXXXX
- 1001 12 UUU,UUU,VV
- 1002 13
预期产量:
我希望TEAMS_REDIRECTED列中的重复项只能选择一次,如下所示:
- ACCOUNT_ID TRANSACTION_ID TEAMS_REDIRECTED
- ---------- -------------- ----------------
- 1001 11 WWW,VV
- 1002 13
我尝试了什么:
我没有直接从tran_party中选择,而是编写了一个内联视图,从tran_party中选择不同的值,如下所示:
- select a.account_id,')
- within group (order by tm_redir.team_code)
- from (select distinct transaction_id,team_id_redirect -- Note this inline view
- from tran_party) tp_redir
- inner join team tm_redir
- on tp_redir.team_id_redirect = tm_redir.team_id
- inner join tran t_redir
- on tp_redir.transaction_id = t_redir.transaction_id
- where t_redir.account_id = a.account_id
- and t_redir.transaction_id != t.transaction_id)
- as teams_redirected
- from tran t inner join account a on t.account_id = a.account_id;
虽然这确实给了我预期的输出,但是当我在实际代码中使用这个解决方案时,只需要13秒来检索一行.因此,我无法使用我已经尝试过的东西.
任何帮助将不胜感激.
解决方法
以下方法删除了内联视图以获取重复项,它使用LISTAGG函数上的REGEXP_REPLACE和RTRIM来获取聚合列表中的不同结果集.因此,它不会进行多次扫描.
- RTRIM(REGEXP_REPLACE(listagg (tm_redir.team_code,')
- WITHIN GROUP (ORDER BY tm_redir.team_code),'([^,]+)(,\1)+','\1'),')
- sql> with tran_party as -- ALL DUMMY DATA ARE IN THESE CTE FOR YOUR REFERENCE
- 2 (select 1 tran_party_id,101 team_id_redirect
- 3 from dual
- 4 union all
- 5 select 2,101 from dual
- 6 union all
- 7 select 3,102 from dual
- 8 union all
- 9 select 4,103 from dual
- 10 union all
- 11 select 5,103 from dual
- 12 union all
- 13 select 6,104 from dual
- 14 union all
- 15 select 7,104 from dual
- 16 union all
- 17 select 8,18 tran as
- 19 (select 11 transaction_id,1034.93 amount from dual
- 20 union all
- 21 select 12,2321.89 from dual
- 22 union all
- 23 select 13,24 account as
- 25 (select 1001 account_id,111 team_id from dual
- 26 union all
- 27 select 1002,28 team as
- 29 (select 101 team_id,'UUU' as team_code from dual
- 30 union all
- 31 select 102,'VV' from dual
- 32 union all
- 33 select 103,'WWW' from dual
- 34 union all
- 35 select 104,'XXXXX' from dual
- 36 union all
- 37 select 105,'Z' from dual)
- 38 -- The Actual Query
- 39 select a.account_id,40 t.transaction_id,41 (SELECT RTRIM(
- 42 REGEXP_REPLACE(listagg (tm_redir.team_code,')
- 43 WITHIN GROUP (ORDER BY tm_redir.team_code),44 '([^,45 ',')
- 46 from tran_party tp_redir
- 47 inner join team tm_redir
- 48 on tp_redir.team_id_redirect = tm_redir.team_id
- 49 inner join tran t_redir
- 50 on tp_redir.transaction_id = t_redir.transaction_id
- 51 where t_redir.account_id = a.account_id
- 52 and t_redir.transaction_id != t.transaction_id)
- 53 AS teams_redirected
- 54 from tran t inner join account a on t.account_id = a.account_id
- 55 /
- ACCOUNT_ID TRANSACTION_ID TEAMS_REDIRECTED
- ---------- -------------- --------------------
- 1001 11 WWW,XXXXX
- 1001 12 UUU,VV
- 1002 13
- sql>