如何在 Oracle 中合并 Union All 的结果

How to merge results of an Union All in Oracle

考虑我有 2 个查询,结果集如下...第一个结果集是针对学生的,因此所有与教师相关的列都是空的。第二个结果集是与教师相关的,与学生相关的列是null 并且它们都共享一些公共列.. 学生:

 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在两个结果集中都是通用的,这基本上意味着教授可以同时是学生......现在我想join/merge这两个查询放到一个共同的结果集中说 'Users' 基本上是老师和学生。

'Users' 的结果集在 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 中实现这一点?感谢你的帮助。

这是一般方法:

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

正如评论中提到的那样,这是一个糟糕的设计(或者可能是使用良好设计的糟糕解决方案)。如果基础 table 是 "person"(仅包含学生和教师的同类信息,例如 UID、姓名、出生日期、电子邮件等),"student" (以UID为外键,只显示学生特有的特征)和"teacher"(教师或讲师也一样),那么设计就可以了,你想要的最终输出可以直接从这些库中得到tables,而不是来自您编写的其他查询的结果。 jva 在 his/her 答案中显示了这些内容。

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

或者,稍微更有效(但有一些风险),group by id, f_name, m_name, l_name 和 select max(...) 仅用于剩余的列。风险在于 m_name 在一个地方是 N 而在另一个地方它是空的;也就是说,您的数据内部不一致。 (如果全部来自一个基地table,"person",那么这个风险应该不存在。)