联接两个表,取最大的一个

时间:2019-03-07 08:19:18

标签: sql oracle join

我想以一对多关系连接两个表,但是只选择第二个表中的一行,第二行的第X列的最大值。

这里是sqlfiddle

这是我的第一个解决方案:

select u.*, a.id, a.address 
from my_user u 
inner join my_address a on u.username = a.username
where a.id = (
  select max(id) from my_address a where a.username = u.username
);

这是第二个解决方案:

select * from (
  select 
    u.username, u.name, u.surname, a.id, a.address,
    row_number() over (partition by a.username order by a.id desc) rn
  from my_user u 
  inner join my_address a on u.username = a.username
) res 
where rn = 1;

您能找出我的不同之处吗?最好的方法是什么,为什么?还有其他更好的解决方案吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

您的查询都可以完成任务。没有一个真的比另一个更好。但是一个可能比另一个快,您可以使用EXPLAIN PLAN来找到。理想情况下,Oracle会为两者提出相同的执行计划,但是对于优化器来说,要检测到这两个查询执行相同的任务是一项艰巨的任务。

从Oracle 12c开始,我将使用CROSS APPLY

select u.*, a.id, a.address 
from my_user u
cross apply
(
  select *
  from my_address ma
  where ma.username = u.username
  order by ma.id desc
  fetch first row only
) a;

在早期版本中(从Oracle 9i开始):

select u.*, a.id, a.address 
from my_user u
join
(
  select ma.*, row_number() over (partition by username order by id desc) as rn
  from my_address ma
) a on a.username = u.username and a.rn = 1;

在更早的版本中:

select u.*, a.id, a.address 
from my_user u
join
(
  select *
  from my_address ma
  where id in (select max(id) from my_address group by username)
) a on a.username = u.username;

演示:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=c0d3ab6617956cb69f979a413026f6db