0

クエリに対する回答を得るために Google と Stack Overflow を検索しましたが、これはよくある質問だと思うので、SQL 語彙が不足しているため、回答を見つけることができないと感じています。私が読む必要があるものの方向に役立つポイントはいつでも大歓迎です.

質問についてですが、Oracle 8i で 3 つのテーブルを結合しようとしています。たとえば、Company テーブル、Invoice テーブル、Jobs テーブルです。Invoice テーブルと Jobs テーブルの間にリンクはありません。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

いつものように、あなたが提供できるどんな助けにも感謝します.

編集:

基本的に、Invoice テーブルと Job テーブルの両方に Company テーブル キー フィールドがありますが、Job テーブルと Invoice テーブルは直接相互にリンクしていません。2 つの請求書と 3 つのジョブがあるときにインスタンスが起動した場合、理想的にはそれを表示したいと思います。逆の場合も同様です。

Company 1   Invoice 1   Job 1
Company 1   Invoice 2   Job 2
Company 1               Job 3

このように問題を見ると、これは私が望んでいたよりも簡単な答えから遠く離れているように感じます。

4

1 に答える 1

1

あなたの要件は、スキーマに問題があることを意味します。この場合の私の最初のアドバイスは、スキーマを変更することです。toまたはto (または NN 関係テーブル) を追加job_idします。invoiceinvoice_idjobinvoice_job

スキーマを更新したくない場合は、結合を行うクエリを実行できます。次のクエリは、基本的に1 対 1 で結合jobします。invoice

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
于 2012-10-03T09:48:54.407 に答える