Выберите первую запись, используя ссылочный идентификатор - PullRequest
0 голосов
/ 08 ноября 2019

Не могу найти решение своей проблемы. Давайте предположим, что у меня есть таблица с 3 столбцами:

ID | contract_number | ref_contract_number 1 | 1 | 1 2 | 2 | 1 3 | 3 | 1 4 | 4 | 1 5 | 5 | 4 6 | 6 | 5 и так далее ...

Как я могу получить первый идентификатор, используя ref_contract_number? Поэтому, если у меня ref_contract_number = 5 или 4, я хочу получить строку с идентификатором 1, потому что это первая запись с соединением между contract_number и ref_contract_number. Нельзя сказать, насколько глубоко идет соединение, результатом должна быть первая запись (последнее соединение) из ref_contract_number. Пожалуйста, помогите!

Мой оператор выбора должен выглядеть следующим образом:

Select........................
where ref_contract_number = 5

и мой результат будет

ID | contract_number | ref_contract_number 1 | 1 | 1

Логика будет такой:Каждая запись имеет номер договора и ссылочный номер договора. Если это первый контракт, то они будут одинаковыми. Но из договора также может прийти новая запись с новым номером, но ссылка на предыдущий договор. Таким образом, ID 2 - 4 - это новая запись для предыдущего контракта с номером 1. ID 5 - это контракт для предыдущего контракта с номером 4, а ID 6 - это новая запись для предыдущего контракта с номером 5. Поэтому мне нужно выбрать самый первыйконтракт для ref_number 5. Соединение будет:

  1. ref_contract = 5 -> контракт = 5
  2. контракт 5 имеет реф контракт 4 -> контракт = 4
  3. контракт 4 имеет реф контракт 1 -> контракт = 1
  4. контракт 1 не имеет другого контракта реф, чем сам -> результат

1 Ответ

1 голос
/ 08 ноября 2019

Использование рекурсивного cte

with 
  -- sample data
  mytable as(
  select *
  from (
     values
        (1, 1, 1) 
       ,(2, 2, 1)
       ,(3, 3, 1)
       ,(4, 4, 1)
       ,(5, 5, 4)
       ,(6, 6, 5)         
     ) t(ID, contract_number, ref_contract_number)
),
rcte as(
  select ID, contract_number, ref_contract_number, 1 level
  from mytable
  where ref_contract_number = 5
  union all
  select p.ID, p.contract_number, p.ref_contract_number, level+1
  from rcte 
  join mytable p  on p.contract_number = rcte.ref_contract_number and p.contract_number != p.ref_contract_number
)
select * 
from  mytable
where contract_number = (select top(1) with ties ref_contract_number top_contract
                         from rcte 
                         order by row_number() over(order by level desc))

Чтобы упростить использование запроса, оберните его во встроенный TVF dbFiddle

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