2017-11-14 7 views
0

表の行ごとにカンマで区切った説明を表示する必要がありますが、リストを区別する必要があり、使用可能な説明の数がいくつかあります。オラクル独自のリストアカウントが

every_description  needs_count 
--------------------------------- 
Bred       yes 
From Vendor     yes 
Grouped      no 
Removed      yes 
Separated      no 
Weaned      yes 

ので一日で、説明はBred, Grouped, Weanedのようなものかもしれないと私は、このhereを述べ、今取り組んでLISTAGGを使用して、ソリューションを使用して重複を削除していますが、私は5 Bred, Grouped, 2 Weanedのような説明のいくつかのためにカウントを追加する必要があります。

は、ここで私はこだわっている私の現在のクエリです:要するに

WITH cages AS (
     SELECT 1234 AS id FROM DUAL 
    UNION SELECT 5678 AS id FROM DUAL 
    UNION SELECT 9012 AS id FROM DUAL 
    UNION SELECT 3456 AS id FROM DUAL 
), cage_comments AS (
     SELECT 1234 AS cage_id, 'Bred' AS description, TO_DATE('11/14/2017', 'MM/DD/YYYY') AS event_date FROM DUAL 
    UNION SELECT 5678 AS cage_id, 'Grouped' AS description, TO_DATE('11/14/2017', 'MM/DD/YYYY') AS event_date FROM DUAL 
    UNION SELECT 9012 AS cage_id, 'Weaned' AS description, TO_DATE('11/14/2017', 'MM/DD/YYYY') AS event_date FROM DUAL 
    UNION SELECT 3456 AS cage_id, 'Weaned' AS description, TO_DATE('11/14/2017', 'MM/DD/YYYY') AS event_date FROM DUAL 
    UNION SELECT 3456 AS cage_id, 'Bred' AS description, TO_DATE('11/02/2017', 'MM/DD/YYYY') AS event_date FROM DUAL 
    UNION SELECT 3456 AS cage_id, 'Grouped' AS description, TO_DATE('11/14/2017', 'MM/DD/YYYY') AS event_date FROM DUAL 
), calendar AS (
    SELECT dt 
    FROM (
    SELECT TRUNC(LAST_DAY(TO_DATE(&month || '/01/' || &year, 'MM/DD/YYYY')) - ROWNUM + 1) dt 
    FROM DUAL CONNECT BY ROWNUM <= 31 
) 
    WHERE dt >= TRUNC(TO_DATE(&month || '/01/' || &year, 'MM/DD/YYYY'), 'MM') 
    ORDER BY dt ASC 
) 

SELECT 
    cal.dt, 
    (
    SELECT 
     CASE 
     WHEN COUNT(cc.cage_id) > 0 THEN RTRIM(
      REGEXP_REPLACE(
      (LISTAGG(cc.description, ',') WITHIN GROUP (ORDER BY cc.description)), 
      '([^,]*)(,\1)+($|,)', 
      '\1\3' 
     ), 
      ',' 
     ) 
     ELSE NULL 
     END 
    FROM cages c 
    LEFT JOIN cage_comments cc ON cc.cage_id = c.id 
    WHERE cc.event_date = cal.dt 
) AS description 
FROM calendar cal 
ORDER BY cal.dt 

- 私はちょうどその日の説明の一部についてCOUNTを追加することの困難を抱えています。上記の場合、November 2, 2017の場合は1 BredNovember 14, 2017の場合は1 Bred, Grouped, 2 Weanedとします。

+0

lad2025 @あなたのケース – lad2025

+0

を再作成するには、表とINSERT INTOをCREATE投稿してください私は、テストケースを追加しました。プラグアンドプレイでなければなりません。カレンダーのパラメータとして '11'と' 2017'を実行してください。 –

答えて

1

現在、(DISTINCTなしで)すべての説明を集計し、正規表現replaceで重複する説明を削除します。これは非常に非効率的です。別名を選択してLISTAGGを適用する方がよいでしょう。

カウントを追加する必要がある場合は、これがさらに重要になります。結合とGROUP BYの記述の結果を取得します。 (特に、DISTINCTが処理されます)。この集約ステップのSELECTに、カウントを含めます。次に、質問の先頭にある追加のテーブルに結果を追加し、LISTAGGに引数を書き換えて、の値が'yes'の場合の数(および空白)に等しいCASE式を追加します。

あなたが使用することができ
+0

ラブリー。このソリューションをありがとう! –

1

SELECT 
    cal.dt, 
    ( 
     SELECT LISTAGG(CASE WHEN COUNT(*)=1 THEN '' 
      ELSE CAST(COUNT(*) AS VARCHAR2(10)) || ' ' END || description, ', ') 
      WITHIN GROUP (ORDER BY description) 
     FROM cages c 
     LEFT JOIN cage_comments cc ON cc.cage_id = c.id 
     WHERE cc.event_date = cal.dt 
     GROUP BY cc.event_date, cc.description 
) AS description 
FROM calendar cal 
ORDER BY cal.dt; 

DBFiddle Demo

+0

これは近いです - ちょっと([DBFiddle](http://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=ebf280ec9288b12950b0a004de4ee568))修正する必要があります。 –

関連する問題