指数結果を制限しながら、SQLで複数のテーブルを接続します
質問
私は私のクエリに対する答えのためにGoogleとStackオーバーフローを検索しましたが、私はこれが一般的な質問になると私が信じるように私の答えを見つけるために私のSQLの語彙の欠如を感じています。私が読む必要があるものの方向に役立つポイントは常に大歓迎です。
質問には、Oracle 8iの3つのテーブルに参加しようとしています。たとえば、会社の表、請求書表とジョブ表との間のリンクがありません。 1つのクエリでは、各請求書のすべてのジョブをすべてのジョブを返すことなく、3つのテーブルすべてをすべての請求書と会社のすべてのジョブにリンクできることを願っています(以下のマイ例の結果を参照)。
見たい:
Company 1 Invoice 1 Job 1
Company 1 Invoice 2 Job 2
Company 1 Invoice 3 Job 3
.
見たくない:
Company 1 Invoice 1 Job 1
Company 1 Invoice 1 Job 2
Company 1 Invoice 1 Job 3
Company 1 Invoice 2 Job 1
Company 1 Invoice 2 Job 2
Company 1 Invoice 2 Job 3
Company 1 Invoice 3 Job 1
Company 1 Invoice 3 Job 2
Company 1 Invoice 3 Job 3
.
あなたが提供できる助けを与えていただきありがとうございます。
編集:
本質的に請求書とジョブテーブルの両方に会社のテーブルキーフィールドがあり、ジョブテーブルと請求書テーブルに直接リンクがないことだけです。 2つの請求書と3つの仕事があるときにインスタンスが起動した場合、理想的にはそれが表示され、逆の逆のようなものがあります。
Company 1 Invoice 1 Job 1
Company 1 Invoice 2 Job 2
Company 1 Job 3
.
このような問題を見ていますが、これは私が望んでいるよりも簡単な答えからさらに離れていると感じさせます。
解決
あなたの要求はあなたがあなたのスキーマに問題があることを意味します。この場合の最初のアドバイスは、スキーマを変更することです.job_id
またはinvoice
へのinvoice_id
をjob
(またはN-Nリレーションシップテーブルinvoice_job
)に追加することです。
スキーマを更新しても構わないと思っていない場合は、結合を行うクエリを作動させることができます。次のquery は基本的にjob
とinvoice
を1対1に結合します。
SELECT c.company_id, ij.job_id, ij.invoice_id
FROM company c
LEFT JOIN (SELECT job_id, invoice_id,
NVL(j.company_id, i.company_id) company_id
FROM (SELECT j.job_id, j.company_id,
row_number() OVER (PARTITION BY company_id
ORDER BY job_id) job_no
FROM job j) j
FULL OUTER JOIN
(SELECT i.invoice_id, i.company_id,
row_number() OVER (PARTITION BY company_id
ORDER BY invoice_id) invoice_no
FROM invoice i) i
ON j.company_id = i.company_id
AND j.job_no = i.invoice_no) ij
ON c.company_id = ij.company_id
.
ここでの結合条件は人工的です。請求書を削除すると、ジョブと請求書の関係が変わる可能性があります。
2つのテーブルが本当に無関係である場合は、代わりに結果を異なる方法で表示することができます。:
SQL> SELECT cj.company_id, cj.jobs,
2 listagg(i.invoice_id, ',')
3 WITHIN GROUP (ORDER BY i.invoice_id) invoices
4 FROM (SELECT c.company_id,
5 listagg(j.job_id, ',') WITHIN GROUP (ORDER BY job_id) jobs
6 FROM company c LEFT JOIN job j ON c.company_id = j.company_id
7 GROUP BY c.company_id) cj
8 LEFT JOIN invoice i ON cj.company_id = i.company_id
9 GROUP BY cj.company_id, cj.jobs;
COMPANY_ID JOBS INVOICES
----------- ------ --------
1 1,2,3 1,2
.