Получить последнюю запись для каждой записи - PullRequest
2 голосов
/ 02 мая 2019

У меня есть таблица, в которой указано, когда продукт был заменен на другой, и этот другой продукт также может отображаться в этой таблице.

Я хочу знать, как написать запрос, где для данного продукта я получаюпоследний доступный (замененный) продукт.

Пример:

    Product_From   Product_To
    -------------------------
    A              E
    A              D
    B              F
    C              B
    D              F
    D              G

Как будет запрос для получения следующего вывода:

    Product_From   Product_Final
    -------------------------
    A              E
    A              F
    A              G
    B              F
    C              F
    D              F
    D              G

Продукт A был заменендля продуктов D и E, но продукт D был заменен на F и G, поэтому продукт A имеет продукты E, F & G в качестве «конечных продуктов».

Проблема заключается в том, что продукты могут иметь различные записи для замены, поэтому я нене знаю, сколько СОЕДИНЕНИЙ мне нужно ...

Ответы [ 2 ]

1 голос
/ 02 мая 2019

Вы можете сделать это с помощью самостоятельного левого соединения:

select 
  p1.product_from,
  coalesce(p2.product_to, p1.product_to) product_final 
from products p1 left join products p2 
on p2.product_from = p1.product_to 

См. Демоверсию .
Результаты:

> product_from | product_final
> :----------- | :------------
> A            | E            
> A            | F            
> A            | G            
> B            | F            
> C            | F            
> D            | F            
> D            | G 
1 голос
/ 02 мая 2019

Это проблема хождения по графику.Решением является рекурсивный CTE:

with p as (
      select v.*
      from (values ('A', 'E'), ('A', 'D'), ('B', 'F'), ('C', 'B'), ('D', 'F'), ('D', 'G')) v(pfrom, pto)
     ),
     cte as (
      select pfrom, pto
      from p
      where not exists (select 1 from p p2 where p2.pfrom = p.pto)
      union all
      select p.pfrom, cte.pto
      from cte join
           p
           on cte.pfrom = p.pto
     )
select *
from cte
order by pfrom, pto;

Здесь - это дБ <> скрипка.

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