web-dev-qa-db-ja.com

LISTAGGからの重複除外

11.2バージョンのOracleを使用しています。 LISTAGGから重複排除したい。

以下は、Oracle dbの既存のデータです。

Speaker | Qualification | Product
P           A              P1
P           B              P2
P           C              P3
P           D              P1
P           E              P2
Q           A              P1
Q           B              P2
Q           C              P1

以下のデータが欲しい:

Spkeaker | Product
P           ;P1;P2;P3;
Q           ;P1;P2;

どなたでもお助けいただけますか。

2
Priyank
select
  speaker,
  listagg(product, ';')
    within group (order by product)
    as products 
from
  (
    select distinct speaker, product
    from existing_data
  ) t
group by speaker
order by speaker ;

テスト: dbfiddle.uk

3
mustaccio

Oracle 19cでは、単純にDISTINCTを使用できます。

SELECT Speaker, LISTAGG(DISTINCT Product, ';') Products
FROM datatable
GROUP BY Speaker

必要に応じて、WITHIN GROUP順序付け句を追加します。

フィドル


ypercubeᵀᴹによる重要な区別

DISTINCTが最新バージョン19cでのみLISTAGGに追加されたようです:

Oracle LiveSQL:19C LISTAGG DISTINCT

1
Akina

DISTINCT値を持つサブクエリの作成を回避するために、通常は次の方法を使用します。

with CTE (Speaker, Qualification, Product) AS (
        SELECT 'P','A','P1' FROM DUAL UNION ALL
        SELECT 'P','B','P2' FROM DUAL UNION ALL
        SELECT 'P','C','P3' FROM DUAL UNION ALL
        SELECT 'P','D','P1' FROM DUAL UNION ALL
        SELECT 'P','E','P2' FROM DUAL UNION ALL
        SELECT 'Q','A','P1' FROM DUAL UNION ALL
        SELECT 'Q','B','P2' FROM DUAL UNION ALL
        SELECT 'Q','C','P1' FROM DUAL
    )
--
--ACTUAL QUERY STARTS FROM HERE
--
SELECT
    SPEAKER,
    ',' || REGEXP_REPLACE(RTRIM(XMLAGG(XMLELEMENT(E, PRODUCT, ',').EXTRACT('//text()')
        ORDER BY
            PRODUCT
    ).GETCLOBVAL(), ','), '([^,]+)(,\1)+', '\1') || ',' AS LIST
FROM
    CTE
GROUP BY
    SPEAKER;

乾杯!! -出力-

S LIST                                                                            
- -------------
P ,P1,P2,P3,                                                                        
Q ,P1,P2,  
1
Tejash