1

PL/SQL で結合を実行して、単一のクエリの一部として複数の子テーブルを持つ親レコードのリストを取得しようとしています。私はオラクルの専門家ではありません。次のようなクエリを書いた場合:

SELECT PEOPLE.PersonName, JOBS.JobName, CREDENTIALS.CredentialName 
  FROM PEOPLE
  LEFT OUTER JOIN JOBS
    ON PEOPLE.PersonName = JOBS.PersonName
  LEFT OUTER JOIN CREDENTIALS
    ON PEOPLE.PersonName = CREDENTIALS.PersonName
  WHERE PEOPLE.PersonName = 'James'

次のように、ジョブと資格情報のすべての組み合わせをリストするテーブルが返されます。

RN PERSON    JOB         CREDENTIAL
1  James     Developer   MBA
2  James     Developer   PhD
3  James     Developer   MCAD
4  James     QA          MBA
5  James     QA          PhD
6  James     QA          MCAD

それは問題ありません。左外部結合が機能することを期待する方法とまったく同じです。しかし、必要なのは、JOB 列と CREDENTIAL 列が各要素を 1 回だけリストし、互いに無関係であることですが、それでも PERSON が James である行にのみ、James の子レコードをリストします。

RN PERSON    JOB         CREDENTIAL
1  James     Developer   MBA
2  James     QA          PhD
3  James     (null)      MCAD

しかし、この結合の書き方がわかりません。(アイデアは、C# コードがクエリ結果を取得し、2 つの子 JOB オブジェクトと 3 つの子 CREDENTIAL オブジェクトへの参照のリストを持つ 1 つの親 PERSON オブジェクトに変換するというものです。

ただし、この例の外には、実際には 3 つ以上の子テーブルがあるため、すべての子の組み合わせの結果である結果セットをフィルター処理することはできません。列を無関係なリストにする必要があります。

これを実現するために複雑な SQL を処理しても構わないと思っていますが、C# 側で結果を組み合わせた複数のクエリではなく、1 つのクエリである必要があります。

助けてくれる人に感謝します!

4

1 に答える 1

0

各リストを列挙し、それを使用して参加する必要があります。

select p.PersonName, j.JobName, c.CredentialName
from Person p left outer join
     (select j.*,
             row_number() over (partition by PersonName order by jobname) as seqnum
      from jobs
     ) j
     on p.PersonName = j.PersonName full outer join
     (select c.*,
             row_number() over (partition by PersonName order by CredentialName) as seqnum
      from Credentials
     ) c
     on p.PersonName = c.PersonName and
        j.seqnum = c.seqnum
WHERE p.PersonName = 'James'

このクエリは、すべての人に seqnum を割り当てるため、より多くの作業を行っています。実際に一度に 1 人だけを選択する場合は、サブクエリに WHERE 句を挿入して効率を高めることができます。

于 2012-09-06T22:01:00.567 に答える