如何在 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",那么这个风险应该不存在。)
考虑我有 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",那么这个风险应该不存在。)