只保留左边的一条记录 table
Keep only one record from left table
我需要在内部联接后获取记录,而没有来自左侧的重复数据 table。
Parent table :
Parent id parent name
1 Douglas
Child table :
Parent id child name
1 George
1 Michael
通过经典的 Oracle Inner 连接,我得到了这个:
Parent id parent name child name
1 Douglas George
1 Douglas Michael
但我需要这个结果:(我需要空值而不是 parents 个名称)
Parent id parent name child name
1 Douglas George
Null Null Michael
当然还有parents和children。
您想在 child id
上进行右联接
select p.parentid,p.parentname,c.childname
from parent p
right join child c
on p.parentid=c.childid
一种方法是使用 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;
要完成这项工作,您必须订购。
"It seems more complicated than I thought. Is there other way without 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
这会生成两个行号,一个用于跟踪父代,一个用于对整个行集进行排序。
使用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)
PARENT_ID PARENT_NAME CHILD_ID CHILD_NAME
---------- ----------- ---------- ----------
1 Douglas 1 George
2 Michael
我需要在内部联接后获取记录,而没有来自左侧的重复数据 table。
Parent table :
Parent id parent name
1 Douglas
Child table :
Parent id child name
1 George
1 Michael
通过经典的 Oracle Inner 连接,我得到了这个:
Parent id parent name child name
1 Douglas George
1 Douglas Michael
但我需要这个结果:(我需要空值而不是 parents 个名称)
Parent id parent name child name
1 Douglas George
Null Null Michael
当然还有parents和children。
您想在 child id
select p.parentid,p.parentname,c.childname
from parent p
right join child c
on p.parentid=c.childid
一种方法是使用 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;
要完成这项工作,您必须订购。
"It seems more complicated than I thought. Is there other way without 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
这会生成两个行号,一个用于跟踪父代,一个用于对整个行集进行排序。
使用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)
PARENT_ID PARENT_NAME CHILD_ID CHILD_NAME
---------- ----------- ---------- ----------
1 Douglas 1 George
2 Michael