Home > Software design >  How can I join on a row to get back to the first relevant row?
How can I join on a row to get back to the first relevant row?

Time:11-07

I have been searching on the net for an answer to a SQL related question. I hope anyone can help me out.

Table1

Item
ABC4

Table 2

Previous-Item New-Item
ABC1 ABC2
ABC1 ABC3
ABC2 ABC3
ABC3 ABC4

I want to join Table 1 (Item) to Table 2 (New-Item) and get all the previous items (back from ABC4 to ABC1. Combinations are possible in the data. Sometimes an item can only be backtracked from 4 to 1 and sometimes directly. This theoretically could go to infinite. So I am looking for a situation how I can make a loop in a join.

My query right now is:

SELECT 
T1.Item, 
T3.Previous-Item 
FROM Table1 T1 (NOLOCK)
LEFT JOIN Table2 T2 (NOLOCK) ON T1.Item = T2.Previous-Item
LEFT LOOP JOIN Table2 T3(NOLOCK) ON T2.Item = T3.Previous-Item

UPDATE:

The expected result would be:

Item Previous-Item
ABC4 ABC3
ABC4 ABC2
ABC4 ABC1

CodePudding user response:

A recursive CTE can do what your LOOP JOIN intends :

CREATE TABLE Table1 ( item varchar(20) )
CREATE TABLE Table2 ( previous_item varchar(20), new_item varchar(20) )

INSERT INTO Table1 (item) 
            values ('ABC4')
INSERT INTO Table2 (previous_item, new_item)
            values ('ABC1', 'ABC2'),
                   ('ABC1', 'ABC3'),
                   ('ABC2', 'ABC3'),
                   ('ABC3', 'ABC4')

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

WITH resursive_cte as (
  select item, item as previous_item, cast(null as varchar(20)) as new_item
  from Table1 -- Anchor (initial records)
  union all
  select recursive_cte.item, Table2.previous_item, Table2.new_item
  from resursive_cte -- Recursive records
       inner join Table2 on Table2.new_item = recursive_cte.previous_item
)          
select distinct item, previous_item
from resursive_cte
where new_item is not null

You can see it working here : db<>fiddle

PS: I have included a SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; command, as Larnu has recommended, so you don't need to use the NOLOCK hint manually on every table if you want to get dirty reads.

  • Related