2016-09-18 72 views
0

考虑我有两个查询与下面的结果集...第一个结果集是为学生,所以有关教师的所有列是空的..第二个结果集是有关的相关学生辅导员和列都为空且二者共享一些常见的列.. 学生:如何合并Oracle的所有联盟的结果

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中实现这一目标?感谢你的帮助。

+0

我认为UNION在这里不是正确的方法。你的2个查询的来源是什么?请显示SQL。无论是学生还是老师,都有一个存储“人员”的源表,或者你有两个不同的表格,这是不好的设计。对于这两种情况,有两种不同的方法,我不知道应该选择哪一种,因为您没有提供足够的信息。 –

+0

@ThomasG这两个查询是复杂的连接查询,但都使用一个常见的来源,称为“人员”。但是无法区分一个人是学生还是教师,只是存储了个人和他的细节。这可能是一个糟糕的设计,但它已经被放置并用于其他数百万个其他地方......假设有另外两张桌子,学生和老师......所以内心加入的学生,人员和其他一些与学生相关的桌子给了我所有的学生细节..同样,内部加入教师表与人,其他人的数据表给我所有的教师的详细信息。 –

+0

看完整的外部加入学生与老师在uid –

回答

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_nameN而在另一个地方它是空的;也就是说,您的数据在内部不一致。 (如果全部来自一个基本表,“人”,那么这个风险就不应该存在。)

+0

我改变了我的解决方案,使得在查询一我加入学生与人,也使确保返回的UID不在教师相关表中。所以,这样我就可以确保(学生只有排除老师)联盟(仅限教师)。似乎工作正常。感谢您的输入 –

+0

'union all'和'group by'方法可能比您所描述的要快。尝试两种方式并决定。祝你好运! – mathguy

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