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 列只列出每个元素一次并且彼此无关 - 但仍然在 PERSON 是 James 的行上并且仅在行上列出 James 的子记录。

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

但我不知道如何写这个加入。(想法是 C# 代码将获取查询结果并将其转换为一个父 PERSON 对象,其中包含对两个子 JOB 对象和三个子 CREDENTIAL 对象的引用列表。

然而,在这个例子之外,实际上有不止两个子表,所以我不能过滤一个结果集,它是所有子组合的产物;我需要列是不相关的列表。

我愿意处理毛茸茸的 SQL 来实现这一点,但它需要是一个查询,而不是多个查询,结果在 C# 端组合。

感谢任何能提供帮助的人!

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。如果您真的一次只选择一个人,您可以将 WHERE 子句放在子查询中以提高效率。

于 2012-09-06T22:01:00.567 回答