如何合并Oracle中的Union All

时间:2016-09-18 19:58:34

标签: sql oracle oracle11g pivot union-all

考虑我有以下结果集的2个查询...第一个结果集适用于学生,因此所有与教师相关的列都为空。第二个结果集与教师有关,与学生相关的列为空他们俩共享几个共同的专栏。 学生:

 uid f_name m_name l_name class school Section Dept. Branch Title
 1   abc    c     dey   2     NYU    1   null    null     null
 2   cde    d     rey   3     CU     2   null    null     null
 3   xyz    r     mey   4     LSU    3   null    null     null

师:

uid f_name m_name l_name class school Section Dept. Branch Title
4    wss    c     tey  null    null     null   Science  Biology  Asso.Prof
2    cde    d     rey  null    null     null   Arts     Music    Asso.Prof
5    rrr    r     jey  null    null     null   Science  Chemistry Prof

如果查看上面的结果集,UID 2在结果集中都很常见,这基本上意味着教授也可以同时成为学生...现在我想加入/合并这两个查询到一个共同的结果集说'用户'基本上是老师和学生。

“用户”的结果集对于UID应该是唯一的。如果我使用union all,UID 2上会有重复项。我需要一个可以合并单行的列的查询...结果集应该是:

1   abc    c     dey   2     NYU    1   null    null     null
2   cde    d     rey   3     CU     2   Arts    Music     Asso.Prof
3   xyz    r     mey   4     LSU    3   null    null     null
4   wss    c     tey  null    null     null   Science  Biology  Asso.Prof
5   rrr    r     jey  null    null     null   Science  Chemistry Prof

上面注2,它同时包含学生和教授的详细信息......

我如何在Oracle中实现这一目标?感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这将是一般方法:

SELECT persons.id
      ,nvl(<some_student_field>, <same_teacher_field) as some_common_field
      ,... 
FROM persons 
     LEFT OUTER JOIN students on (person.id = students.person_id)
     LEFT OUTER JOIN teachers on (person.id = teachers.person_id)
WHERE <mandatory_field_for_students> IS NOT NULL
   OR <mandatory_field_for_teachers> IS NOT NULL

答案 1 :(得分:1)

正如评论中所提到的,这是一个糟糕的设计(或者使用好的设计可能是一个糟糕的解决方案)。如果基表是“人”(仅包含学生和教师的同类信息,如UID,姓名,出生日期,电子邮件等),“学生”(UID作为外键,并显示只有特定于学生的特征)和“老师”(教师或教师相同),然后设计很好,您可以直接从这些基表获得所需的最终输出,而不是从您编写的其他查询的结果中获得。 jva在他/她的回答中展示了这些内容。

如果您真的需要忍受,使用现有查询的方法是使用union all - 但是您必须group by uid,并且对于每列,您必须选择max(...) } - 例如max(f_name)max(school)。在SELECT子句中使用列别名,例如select .... , max(school) as school, ...

或者,稍微更有效(但有一些风险),group by id, f_name, m_name, l_name并仅为其余列选择max(...)。风险在于,m_name在一个地方N,在另一个地方,它是空的;也就是说,您的数据内部不一致。 (如果它全部来自一个基表,“人”,那么这种风险就不存在了。)