Pergunta

I am facing a scenario in which I have a foreign reference field of the same table and I need to get the list of values of such foreign references. For eg:

Field1 | Field2
----------------
X      |   Y
Y      |   Z
Z      |   A

Now I want to cascade select Field2 as in I want the output to be {Y,Z,A}.

Is there a way to achieve this?

Foi útil?

Solução

I think SQL recursive queries is what you're searching for. Its syntax looks like this:

WITH RECURSIVE <cte_name> (column, ...) AS (
<non-recursive_term>
UNION ALL
<recursive_term>)
SELECT ... FROM <cte_name>;

In your case it will look like this:

  1. Create table and populate it:

    create table example (field1 char(1), field2 char(1));
    insert into example values ('X', 'Y');
    insert into example values ('Y', 'Z');
    insert into example values ('Z', 'A');
    select * from example;
    

    Result:

     field1 | field2 
     -------+--------
      X     | Y
      Y     | Z
      Z     | A
     (3 rows)
    
  2. Query:

     WITH RECURSIVE linked_example(list, first, last) AS (
       SELECT field1 || ', ' || field2, field1, field2 FROM example
       UNION ALL
       SELECT list || ', ' || field2, first, field2
         FROM
           linked_example, example
         WHERE
           last = field1
     )
     SELECT * from linked_example;
    

    Result:

         list    | first | last 
     ------------+-------+------
      X, Y       | X     | Y
      Y, Z       | Y     | Z
      Z, A       | Z     | A
      X, Y, Z    | X     | Z
      Y, Z, A    | Y     | A
      X, Y, Z, A | X     | A
     (6 rows)
    
  3. Now, just limit the query with WHERE clause:

     WITH RECURSIVE linked_example(list, first, last) AS (
       SELECT field1 || ', ' || field2, field1, field2 FROM example
       UNION ALL
       SELECT list || ', ' || field2, first, field2
         FROM
           linked_example, example
         WHERE
           last = field1
     )
     SELECT * from linked_example WHERE first = 'Y';
    

    Result:

       list   | first | last 
     ---------+-------+------
      Y, Z    | Y     | Z
      Y, Z, A | Y     | A
     (2 rows)
    

    As you can see, the last row is exactly what you want.

If you want more information and examples regarding SQL recursive queries, you can read my two articles covering this topic:

Outras dicas

You can achieve this simply using a jonction:

select a.field1, a.field2, b.field2
from my_table a
inner join my_table b
on a.field2 =b.field1

SQL FIddle sample

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top