объединить две таблицы, взяв одну с максимальным значением - PullRequest
0 голосов
/ 07 марта 2019

Я хотел бы объединить две таблицы в отношении «один ко многим», но выбрал только одну строку во второй таблице, ту, которая имеет максимальное значение в столбце 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 Ответ

2 голосов
/ 07 марта 2019

Оба ваших запроса подходят для этой задачи. Ни один действительно лучше, чем другой. Но один может быть быстрее другого, что вы можете узнать с помощью 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...