Rac*_*cha 5 sql oracle aggregate aggregate-functions
这是我正在尝试做的和我得到的最简单的工作示例:
我有一个查询如下:
/*
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, 11, 102 from dual
union all
select 4, 12, 103 from dual
union all
select 5, 12, 103 from dual
union all
select 6, 12, 104 from dual
union all
select 7, 13, 104 from dual
union all
select 8, 13, 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;
Run Code Online (Sandbox Code Playgroud)
注意: tran_party.team_id_redirect是引用team.team_id的外键.
当前输出:
ACCOUNT_ID TRANSACTION_ID TEAMS_REDIRECTED
---------- -------------- ----------------
1001 11 WWW, WWW, XXXXX
1001 12 UUU, UUU, VV
1002 13
Run Code Online (Sandbox Code Playgroud)
预期产量:
我希望TEAMS_REDIRECTED
列中的重复项只能选择一次,如下所示:
ACCOUNT_ID TRANSACTION_ID TEAMS_REDIRECTED
---------- -------------- ----------------
1001 11 WWW, XXXXX
1001 12 UUU, VV
1002 13
Run Code Online (Sandbox Code Playgroud)
我尝试了什么:
tran_party
我没有直接选择,而是编写了一个内联视图,从tran_party中选择不同的值,如下所示:
select a.account_id,
t.transaction_id,
(select listagg (tm_redir.team_code, ', ')
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;
Run Code Online (Sandbox Code Playgroud)
虽然这确实给了我预期的输出,但是当我在实际代码中使用这个解决方案时,只需要13秒来检索一行.因此,我无法使用我已经尝试过的东西.
任何帮助将不胜感激.
以下方法摆脱了内联视图来获取重复项,它使用REGEXP_REPLACE
andRTRIM
函数LISTAGG
来获取不同的结果集aggregated list
. 因此,它不会执行多次扫描。
将这段添加到您的代码中,
RTRIM(REGEXP_REPLACE(listagg (tm_redir.team_code, ',')
WITHIN GROUP (ORDER BY tm_redir.team_code),
'([^,]+)(,\1)+', '\1'),
',')
Run Code Online (Sandbox Code Playgroud)
修改后的查询-
SQL> with tran_party as -- ALL DUMMY DATA ARE IN THESE CTE FOR YOUR REFERENCE
2 (select 1 tran_party_id, 11 transaction_id, 101 team_id_redirect
3 from dual
4 union all
5 select 2, 11, 101 from dual
6 union all
7 select 3, 11, 102 from dual
8 union all
9 select 4, 12, 103 from dual
10 union all
11 select 5, 12, 103 from dual
12 union all
13 select 6, 12, 104 from dual
14 union all
15 select 7, 13, 104 from dual
16 union all
17 select 8, 13, 105 from dual),
18 tran as
19 (select 11 transaction_id, 1001 account_id, 1034.93 amount from dual
20 union all
21 select 12, 1001, 2321.89 from dual
22 union all
23 select 13, 1002, 3201.47 from dual),
24 account as
25 (select 1001 account_id, 111 team_id from dual
26 union all
27 select 1002, 112 from dual),
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 '([^,]+)(,\1)+', '\1'),
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>
Run Code Online (Sandbox Code Playgroud)