sql – SELECT列表中子查询内的不同LISTAGG

前端之家收集整理的这篇文章主要介绍了sql – SELECT列表中子查询内的不同LISTAGG前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是我正在尝试做的和我得到的最小的工作示例:

我有一个查询如下:

  1. /*
  2. with tran_party as -- ALL DUMMY DATA ARE IN THESE CTE FOR YOUR REFERENCE
  3. (select 1 tran_party_id,11 transaction_id,101 team_id_redirect
  4. from dual
  5. union all
  6. select 2,11,101 from dual
  7. union all
  8. select 3,102 from dual
  9. union all
  10. select 4,12,103 from dual
  11. union all
  12. select 5,103 from dual
  13. union all
  14. select 6,104 from dual
  15. union all
  16. select 7,13,104 from dual
  17. union all
  18. select 8,105 from dual),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),account as
  24. (select 1001 account_id,111 team_id from dual
  25. union all
  26. select 1002,112 from dual),team as
  27. (select 101 team_id,'UUU' as team_code from dual
  28. union all
  29. select 102,'VV' from dual
  30. union all
  31. select 103,'WWW' from dual
  32. union all
  33. select 104,'XXXXX' from dual
  34. union all
  35. select 105,'Z' from dual)
  36. -- */
  37. -- The Actual Query
  38. select a.account_id,t.transaction_id,(select listagg (tm_redir.team_code,',')
  39. within group (order by tm_redir.team_code)
  40. from tran_party tp_redir
  41. inner join team tm_redir
  42. on tp_redir.team_id_redirect = tm_redir.team_id
  43. inner join tran t_redir
  44. on tp_redir.transaction_id = t_redir.transaction_id
  45. where t_redir.account_id = a.account_id
  46. and t_redir.transaction_id != t.transaction_id)
  47. as teams_redirected
  48. 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.

当前输出

  1. ACCOUNT_ID TRANSACTION_ID TEAMS_REDIRECTED
  2. ---------- -------------- ----------------
  3. 1001 11 WWW,WWW,XXXXX
  4. 1001 12 UUU,UUU,VV
  5. 1002 13

预期产量:

我希望TEAMS_REDIRECTED列中的重复项只能选择一次,如下所示:

  1. ACCOUNT_ID TRANSACTION_ID TEAMS_REDIRECTED
  2. ---------- -------------- ----------------
  3. 1001 11 WWW,VV
  4. 1002 13

我尝试了什么:

我没有直接从tran_party中选择,而是编写了一个内联视图,从tran_party中选择不同的值,如下所示:

  1. select a.account_id,')
  2. within group (order by tm_redir.team_code)
  3. from (select distinct transaction_id,team_id_redirect -- Note this inline view
  4. from tran_party) tp_redir
  5. inner join team tm_redir
  6. on tp_redir.team_id_redirect = tm_redir.team_id
  7. inner join tran t_redir
  8. on tp_redir.transaction_id = t_redir.transaction_id
  9. where t_redir.account_id = a.account_id
  10. and t_redir.transaction_id != t.transaction_id)
  11. as teams_redirected
  12. from tran t inner join account a on t.account_id = a.account_id;

虽然这确实给了我预期的输出,但是当我在实际代码中使用这个解决方案时,只需要13秒来检索一行.因此,我无法使用我已经尝试过的东西.

任何帮助将不胜感激.

解决方法

以下方法删除了内联视图以获取重复项,它使用LISTAGG函数上的REGEXP_REPLACE和RTRIM来获取聚合列表中的不同结果集.因此,它不会进行多次扫描.

将此部分添加到您的代码中,

  1. RTRIM(REGEXP_REPLACE(listagg (tm_redir.team_code,')
  2. WITHIN GROUP (ORDER BY tm_redir.team_code),'([^,]+)(,\1)+','\1'),')

修改查询

  1. sql> with tran_party as -- ALL DUMMY DATA ARE IN THESE CTE FOR YOUR REFERENCE
  2. 2 (select 1 tran_party_id,101 team_id_redirect
  3. 3 from dual
  4. 4 union all
  5. 5 select 2,101 from dual
  6. 6 union all
  7. 7 select 3,102 from dual
  8. 8 union all
  9. 9 select 4,103 from dual
  10. 10 union all
  11. 11 select 5,103 from dual
  12. 12 union all
  13. 13 select 6,104 from dual
  14. 14 union all
  15. 15 select 7,104 from dual
  16. 16 union all
  17. 17 select 8,18 tran as
  18. 19 (select 11 transaction_id,1034.93 amount from dual
  19. 20 union all
  20. 21 select 12,2321.89 from dual
  21. 22 union all
  22. 23 select 13,24 account as
  23. 25 (select 1001 account_id,111 team_id from dual
  24. 26 union all
  25. 27 select 1002,28 team as
  26. 29 (select 101 team_id,'UUU' as team_code from dual
  27. 30 union all
  28. 31 select 102,'VV' from dual
  29. 32 union all
  30. 33 select 103,'WWW' from dual
  31. 34 union all
  32. 35 select 104,'XXXXX' from dual
  33. 36 union all
  34. 37 select 105,'Z' from dual)
  35. 38 -- The Actual Query
  36. 39 select a.account_id,40 t.transaction_id,41 (SELECT RTRIM(
  37. 42 REGEXP_REPLACE(listagg (tm_redir.team_code,')
  38. 43 WITHIN GROUP (ORDER BY tm_redir.team_code),44 '([^,45 ',')
  39. 46 from tran_party tp_redir
  40. 47 inner join team tm_redir
  41. 48 on tp_redir.team_id_redirect = tm_redir.team_id
  42. 49 inner join tran t_redir
  43. 50 on tp_redir.transaction_id = t_redir.transaction_id
  44. 51 where t_redir.account_id = a.account_id
  45. 52 and t_redir.transaction_id != t.transaction_id)
  46. 53 AS teams_redirected
  47. 54 from tran t inner join account a on t.account_id = a.account_id
  48. 55 /
  49.  
  50. ACCOUNT_ID TRANSACTION_ID TEAMS_REDIRECTED
  51. ---------- -------------- --------------------
  52. 1001 11 WWW,XXXXX
  53. 1001 12 UUU,VV
  54. 1002 13
  55.  
  56. sql>

猜你在找的MsSQL相关文章