只保留左表中的一条记录

时间:2017-03-16 16:03:22

标签: sql oracle oracle10g

我需要在内部连接后获取记录而不从左表中获取重复数据。

Parent table :
Parent id  parent name
1          Douglas 

Child table :
Parent id  child name
1             George
1             Michael 

使用经典的Oracle Inner join,我得到了:

Parent id  parent name  child name 
1          Douglas      George
1          Douglas      Michael 

但我需要这个结果:(我需要空值而不是父母名字)

Parent id  parent name  child name 
1          Douglas      George
Null       Null         Michael 

当然,还有更多的父母和孩子。

3 个答案:

答案 0 :(得分:0)

您希望在child id

上进行正确的加入
select p.parentid,p.parentname,c.childname
from parent p
right join child c
on p.parentid=c.childid

答案 1 :(得分:0)

执行此操作的一种方法是使用a CURSOR EXPRESSION

select parent_id
       , parent_name
       , cursor ( select child_id
                         , child_name
                  from child
                  where child.parent_id = parent.parent_id )
from parent

此呈现效果取决于您用于运行它的客户端。有些人比其他人更好地处理输出。

或者,您可以将其视为显示问题。例如,在SQL * Plus中,您可以使用BREAK ON parent_id ON parent_name来抑制重复值。 Find out more

select parent.parent_id
       , parent.parent_name
       , child.child_id
       , child.child_name
from parent 
     join child
         on child.parent_id = parent.parent_id
order by parent.parent_id, child.child_id;

要完成这项工作,您必须订购。

  

“看起来比我想象的要复杂。没有Cursor还有其他办法吗?”

那是因为结果集是扁平的而不是锯齿状的。调整查询以实现显示功能通常会导致笨重或冗长的SQL。

谈到哪一个,这是另一个解决方案:

with cte as (
   select parent.parent_id
          , parent.parent_name
          , child.child_id
          , child.child_name
          , row_number() over (partition by parent.parent_id 
                                             order by child.child_id ) as prn
          , row_number() over (order by  parent.parent_id , child.child_id ) as rn
    from parent 
         join child
             on child.parent_id = parent.parent_id
)
select case when prn = 1 then parent_id else null end as parent_id
       , case when prn = 1 then parent_name else null end as parent_name
       , child_id
       , child_name
from cte
order by rn

这会生成两个行号,一个用于跟踪父项,一个用于对整个行集进行排序。

答案 2 :(得分:0)

使用row_number()lag()lead(),如下所示:

select case when rn = 1 then parent_id end parent_id, 
       case when rn = 1 then parent_name end parent_name, 
       child_id, child_name 
  from (select p.parent_id, p.parent_name, c.child_id, c.child_name, 
               row_number() over (partition by p.parent_id order by c.child_id) rn
          from parents p join children c on p.parent_id = c.parent_id)

<强> rextester demo

 PARENT_ID PARENT_NAME   CHILD_ID CHILD_NAME
---------- ----------- ---------- ----------
         1 Douglas              1 George
                                2 Michael