2016-12-12 7 views
1

私の目的は、同じOracle SQLデータベース・スキーマ内に、合計50個の表からのデータのボート・ロードを示すデータセットを生成することです。最初を除く各テーブルには限りレポートとして私が心配、二つの要素建物だ、から構成されていますOracle SQL:コンポーネント表からのエントリを一度表示する

  • 最初のテーブルの上の行に一致する外部キー識別子を

これらのテーブルの1つには、1つのケースに対応する行が多数あり、テーブルからテーブルまでの行数は同じではありません。

私の目的は、最初のテーブルの各行を、他のテーブルのすべての結果を一度表示するのに必要な回数だけ表示させることです。だから、(多くのテーブルを除く)は、このような何か:

CASE_FILE_ID INITIATED_DATE INSPECTION_DATE PAYMENT_DATE ACTION_DATE 
------------ -------------- --------------- ------------ ----------- 
     1000 10-JUL-1986  14-JUL-1987 10-JUL-1986    
     1000     14-JUL-1988 10-JUL-1987    
     1000     14-JUL-1989 10-JUL-1988    
     1000         10-JUL-1989    

私の現在のSQLコード(5つのテーブルにまで縮小したが、残りはすべてT1-T4と同じフォーマットに従う):

SELECT DISTINCT 
    A.CASE_FILE_ID, 
    T1.DATE AS INITIATED_DATE, 
    T2.DATE AS INSPECTION_DATE, 
    T3.DATE AS PAYMENT_DATE, 
    T4.DATE AS ACTION_DATE 
FROM 
    RECORDS.CASE_FILE A 
    LEFT OUTER JOIN RECORDS.INITIATE T1 ON A.CASE_FILE_ID = T1.CASE_FILE_ID 
    LEFT OUTER JOIN RECORDS.INSPECTION T2 ON A.CASE_FILE_ID = T2.CASE_FILE_ID 
    LEFT OUTER JOIN RECORDS.PAYMENT T3 ON A.CASE_FILE_ID = T3.CASE_FILE_ID 
    LEFT OUTER JOIN RECORDS.ACTION T4 ON A.CASE_FILE_ID = T4.CASE_FILE_ID 
ORDER BY 
    A.CASE_FILE_ID 

問題は、この出力結果が別のの組み合わせになります。;上記の例では、ケース1000の4行ではなく、A.CASE_FILE_ID = '1000'の 'WHERE'句を追加した場合、12行(1開始日* 3検査日* 4支払日= 12行)。表の数が増えるにつれて、これは表示とランタイムの両方で非常に高速になります。

上記の理想に近いような出力を得るには、どの日付を1回だけ表示するのが最適ですか?それに失敗すると、たとえいくつかの日付がその中で繰り返されても、すべての日付を表示する必要があるので、1つのCASE_FILEに対して複数の行だけを表示する方法がありますか?

+2

上記の描画データ(SQL)1より表示機能の詳細です。上記のデータを表示する仕組みは何ですか?クリスタルレポート? PHP?通常、このタイプのブレークロジックは、ユーザーエクスペリエンス(UX) – xQbert

+0

の一部として、ユーザーインターフェイス(UI)内で実行されます。レンダリングは、黙示によるものよりも多くのものが意図されています。しかし、Gordon Linoffの2番目の方法はこれを正確に示しています。 SSRSは最終的な表示メカニズムになります... Excelに直接アクセスできる必要があることを除いて、できるだけ有用な生のテーブルは理想的です行グループ等を含む。ありがたいことに、それはすでにあります。 –

+0

SSRSの場合は、クエリをレポートにリンクすると簡単になります。http://stackoverflow.com/questions/12940805/blank-out-duplicate-column-values-in-sql-reporting-services "テキストボックスのHideDuplicatesを設定するプロパティを含むグループ名に「 – xQbert

答えて

0

良い方法はありませんが、2通りの方法があります。 1つの方法には、各テーブルと複雑な外部結合のサブクエリが含まれます。 2番目のサブクエリはサブクエリとunion allです。のは、そのいずれかで行こう:

SELECT CASE_FILE_ID, 
     MAX(INITIATED_DATE) as INITIATED_DATE, 
     MAX(INSPECTION_DATE) as INSPECTION_DATE, 
     MAX(PAYMENT_DATE) as PAYMENT_DATE, 
     MAX(ACTION) as ACTION 
FROM ((SELECT A.CASE_FILE_ID, NULL as INITIATED_DATE, NULL as INSPECTION_DATE, 
       NULL as PAYMENT_DATE, NULL as ACTION_DATE, 
       1 as seqnum 
     FROM RECORDS.CASE_FILE A 
    ) UNION ALL 
     (SELECT T1.CASE_FILE_ID, DATE as INITIATED_DATE, NULL as INSPECTION_DATE, 
       NULL as PAYMENT_DATE, NULL as ACTION_DATE, 
       ROW_NUMBER() OVER (PARTITION BY CASE_FILE_ID ORDER BY DATE) as seqnum 
     FROM RECORDS.INITIATE 
    ) UNION ALL 
     (SELECT T1.CASE_FILE_ID, NULL as INITIATED_DATE, DATE as INSPECTION_DATE, 
       NULL as PAYMENT_DATE, NULL as ACTION_DATE, 
       ROW_NUMBER() OVER (PARTITION BY CASE_FILE_ID ORDER BY DATE) as seqnum 
     FROM RECORDS.INSPECTION 
    ) UNION ALL 
     (SELECT T1.CASE_FILE_ID, NULL as INITIATED_DATE, NULL as INSPECTION_DATE, 
       DATE as PAYMENT_DATE, NULL as ACTION_DATE, 
       ROW_NUMBER() OVER (PARTITION BY CASE_FILE_ID ORDER BY DATE) as seqnum 
     FROM RECORDS.PAYMENT 
    ) UNION ALL 
     (SELECT T1.CASE_FILE_ID, NULL as INITIATED_DATE, NULL as INSPECTION_DATE, 
       NULL as PAYMENT_DATE, ACTION as ACTION_DATE, 
       ROW_NUMBER() OVER (PARTITION BY CASE_FILE_ID ORDER BY DATE) as seqnum 
     FROM RECORDS.ACTION 
    ) 
    ) a 
GROUP BY CASE_FILE_ID, seqnum; 

うーん、密接に関連して解決策を維持するために簡単です:

SELECT CASE_FILE_ID, 
     MAX(CASE WHEN type = 'INITIATED' THEN DATE END) as INITIATED_DATE, 
     MAX(CASE WHEN type = 'INSPECTION' THEN DATE END) as INSPECTION_DATE, 
     MAX(CASE WHEN type = 'PAYMENT' THEN DATE END) as PAYMENT_DATE, 
     MAX(CASE WHEN type = 'ACTION' THEN DATE END) as ACTION 
FROM ((SELECT A.CASE_FILE_ID, NULL as TYPE, NULL as DATE, 
       1 as seqnum 
     FROM RECORDS.CASE_FILE A 
    ) UNION ALL 
     (SELECT T1.CASE_FILE_ID, 'INSPECTION', DATE, 
       ROW_NUMBER() OVER (PARTITION BY CASE_FILE_ID ORDER BY DATE) as seqnum 
     FROM RECORDS.INITIATE 
    ) UNION ALL 
     (SELECT T1.CASE_FILE_ID, 'INSPECTION', DATE, 
       ROW_NUMBER() OVER (PARTITION BY CASE_FILE_ID ORDER BY DATE) as seqnum 
     FROM RECORDS.INSPECTION 
    ) UNION ALL 
     (SELECT T1.CASE_FILE_ID, 'PAYMENT', DATE, 
       ROW_NUMBER() OVER (PARTITION BY CASE_FILE_ID ORDER BY DATE) as seqnum 
     FROM RECORDS.PAYMENT 
    ) UNION ALL 
     (SELECT T1.CASE_FILE_ID, 'ACTION', DATE, 
       ROW_NUMBER() OVER (PARTITION BY CASE_FILE_ID ORDER BY DATE) as seqnum 
     FROM RECORDS.ACTION 
    ) 
    ) a 
GROUP BY CASE_FILE_ID, seqnum; 
+0

」と表示されます(これまでのコードよりもはるかに高速です)。どうもありがとうございました! –

関連する問題