簡體   English   中英

SELECT列表中子查詢內的不同LISTAGG

[英]Distinct LISTAGG that is inside a subquery in the SELECT list

這是我正在嘗試做的和我得到的最小的工作示例:

我有一個查詢如下:

/*
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;

注意: 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

預期產量:

我希望TEAMS_REDIRECTED列中的重復項只能選擇一次,如下所示:

ACCOUNT_ID TRANSACTION_ID TEAMS_REDIRECTED
---------- -------------- ----------------
1001       11             WWW, XXXXX
1001       12             UUU, VV
1002       13

我嘗試了什么:

tran_party直接從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;

雖然這確實給了我預期的輸出,但是當我在實際代碼中使用這個解決方案時,只需要13秒來檢索一行。 因此,我無法使用我已經嘗試過的東西。

任何幫助將不勝感激。

以下方法刪除了內聯視圖以獲取重復項,它使用LISTAGG函數上的REGEXP_REPLACERTRIM來獲取aggregated list的不同結果集。 因此,它不會進行多次掃描。

將此片段添加到您的代碼中

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, 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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM