如何在Oracle中获取不匹配的行

时间:2014-01-06 11:33:18

标签: sql oracle

任何人都可以帮我从Oracle中的两个表中获取不匹配的行吗?

表:名称

Class_id        Stud_name
S001          JAMES
S001          PETER
S002          MARK

表:课程

 Course_id   Stud_name
  S001       JAMES
  S001       KEITH
  S002       MARK

输出

我需要将行显示为

   CLASS ID    STUD_NAME_FROM_NAME_TABLE    STUD_NAME_FROM_COURSE_TABLE
   --------------------------------------------------------------------- 
    S001          PETER                        KEITH

我使用Oracle连接来获取不匹配的名称:

      SELECT * 
        FROM Names, Course 
       WHERE Names.Class_id=Course.Course_id 
         AND Names.Stud_name<>Course.Stud_name   

此查询返回重复的行。

5 个答案:

答案 0 :(得分:1)

获取Names

中不匹配的行
 SELECT * FROM Names
 WHERE 
 NOT EXISTS
 (SELECT 'x' from Course 
  WHERE 
  Names.Class_id = Course.Course_id AND 
  Names.Stud_name = Course.Stud_name)

获取NamesCourse中不匹配的行!

 SELECT Names.Class_id,Names.Stud_name,C1.Stud_name
 FROM Names , Course C1
 WHERE Names.Class_id = C1.Course_id AND
 NOT EXISTS
 (SELECT 'x' from Course C2
  WHERE 
  Names.Class_id = C2.Course_id AND 
  Names.Stud_name = C2.Stud_name);

答案 1 :(得分:1)

如果你坚持加入,你可以使用这个:

SELECT * 
FROM Names
   FULL OUTER JOIN Course ON Names.Class_id=Course.Course_id 
      AND Names.Stud_name = Course.Stud_name
WHERE Names.Stud_name IS NULL or Course.Stud_name IS NULL

答案 2 :(得分:0)

当您要求不匹配的行时,我假设您希望names中存在但course中不存在的行。

如果是这种情况,你可能会在

之后
select * from names 
 where (class_id, stud_name ) not in 
   (select course_id, stud_name from course);

您的查询返回了重复的行,因为names中的每个行选择了course中满足where所有行条件。

因此,对于S001, PETER中的names行,S001, JAMES S001, KEITH符合该条件,因此,该行是“两次返回。

编辑由于不清楚stud_name是主键还是唯一(并且在第二眼看来我认为不是),你可能想要一个

select * from names 
 where not exists (
   select 1 from course where
      names.class_id  =  course.course_id and
      names.stud_name <> course.stud_name
 )

编辑II 如果您坚持使用join(根据您的评论),您可能想尝试

select distinct names.* from...

答案 3 :(得分:0)

好吧,我不确定我是否理解你的要求。我想你想要一个列表,其中列表和课程表中的学生列表不同。然后你想要显示课堂上的ID和学生,但不是课程中的学生和课程中但不在课堂上的学生。

为此,您将完全外部加入表格。这将为您提供课堂和课程的学生,课堂上而不是课程的学生,以及课程中而非课堂上的学生。过滤结果,其中class_id或course_id为null,然后在课程或课程中让学生失踪。最后一组由id和列出学生。

select coalesce(class.class_id, course.course_id) as id
  , listagg(class.stud_name, ',') within group (order by class.stud_name) as missing_in_course
  , listagg(course.stud_name, ',') within group (order by course.stud_name) as missing_in_class
from class 
full outer join course 
on (class.class_id = course.course_id and class.stud_name = course.stud_name)
where class.class_id is null or course.course_id is null
group by coalesce(class.class_id, course.course_id);

以下是显示其工作原理的SQL小提琴:http://sqlfiddle.com/#!4/8aaaa/2

编辑:在Oracle 9i中没有listagg。您可以使用inofficial函数wm_concat代替:

select coalesce(class.class_id, course.course_id) as id
  , wm_concat(class.stud_name) as missing_in_course
  , wm_concat(course.stud_name) as missing_in_class
from class 
full outer join course 
on (class.class_id = course.course_id and class.stud_name = course.stud_name)
where class.class_id is null or course.course_id is null
group by coalesce(class.class_id, course.course_id);

答案 4 :(得分:0)

希望它可以帮到你

  with not_in_class as 
      (select a.*
         from Names a
        where not exists ( select 'x'
                         from course b
                        where b.Course_id = a.class_id 
                          and a.Stud_name = b.Stud_name)),
    not_in_course as 
      (select b.*
         from course b
        where not exists ( select 'x'
                         from Names a
                        where b.Course_id = a.class_id 
                          and a.Stud_name = b.Stud_name))
    select x.class_id, 
           x.Stud_name NOT_IN_CLASS, 
           y.stud_name  NOT_IN_COURSE
      from not_in_class x, not_in_course y
     where x.class_id = y.course_id

输出

| CLASS_ID | NOT_IN_CLASS | NOT_IN_COURSE |
|----------|--------------|---------------|
|     S001 |        PETER |         KEITH |

唯一的问题是,如果给定id的两个表中存在多个不匹配,则它适用于特定id的单个不匹配。如果同一个id存在多个不匹配,则需要返工。