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;
どなたでもお助けいただけますか。
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
Oracle 19cでは、単純にDISTINCT
を使用できます。
SELECT Speaker, LISTAGG(DISTINCT Product, ';') Products
FROM datatable
GROUP BY Speaker
必要に応じて、WITHIN GROUP順序付け句を追加します。
ypercubeᵀᴹによる重要な区別
DISTINCTが最新バージョン19cでのみLISTAGGに追加されたようです:
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,