Home > Mobile >  How to match a value in one column to another column based on hierarchy level
How to match a value in one column to another column based on hierarchy level

Time:02-10

I have a table that contains 4 columns: entry_id, NAME, type, upper_id.

enter image description here

Each entry_id corresponds to a specific upper_id. There can be many different entry_id's that correspond to SAME upper_id. The column type represent the level of that entry in terms of hierarchy.

1 --> First level
2 --> Second level
3 --> Third level

I need to match what is in the upper_id to the entry_id in order to add another column for upper_name which will be found in the same table column name. In the example above, if upper_id = '1001' for an entry_id, I need to find this value in the entry_id and grab the name found.

An entry_id with type = '1' will always have an upper_id that has a value in the entry_id with a type = '2'. And an entry_id with a type = '2' will always have an upper id that has a value in entry_id with a type = '3'. An entry_id with type = '3' will never have an upper_id, and its upper_name column will be NULL.

The results will look like this:

enter image description here

CREATE TABLE TBL_1
(     ENTRY_ID int,
      NAME string,
      TYPE int,
      UPPER_ID int
);

INSERT INTO TBL_1
values
(1234,'bichon',1,'1001'),
(1124,'yorkie',1,'1001'),
(1009,'golden',1,'1001'),
(6722,'poodle',1,'1001'),
(1001,'canine',2,'2002'),
(2002,'animal',3,NULL)

Do you know how I can formulate a query that allows me to include an "upper_name" column from the data already in the table?

CodePudding user response:

LEFT JOIN is the key.

WITH table_data (ENTRY_ID, NAME, TYPE, UPPER_ID) AS (
  SELECT * 
  FROM values
    (1234,'bichon',1,1001),
    (1124,'yorkie',1,1001),
    (1009,'golden',1,1001),
    (6722,'poodle',1,1001),
    (1001,'canine',2,2002),
    (2002,'animal',3,NULL)
)
SELECT t1.*,
    t2.name as upper_name
FROM table_data AS t1
LEFT JOIN table_data AS t2
    ON t1.UPPER_ID = t2.ENTRY_ID
        AND t1.type  1 = t2.type

gives:

ENTRY_ID NAME TYPE UPPER_ID UPPER_NAME
1234 bichon 1 1001 canine
1124 yorkie 1 1001 canine
1009 golden 1 1001 canine
6722 poodle 1 1001 canine
1001 canine 2 2002 animal
2002 animal 3

CodePudding user response:

left join the table with itself as following:

select 
t1.ENTRY_ID ,
t1.NAME,
t1.TYPE,
t1.UPPER_ID,
t2.NAME as upper_name

from TBL_1 as t1
left join TBL_1 as t2 on t1.UPPER_ID = t2.ENTRY_ID

The LEFT JOIN keyword returns all records from the left table (t1), and the matching records from the right table (t2),in case no matching record from the right table it will return null for its selected columns. enter image description here

CodePudding user response:

Join the table to itself on upper_id = entry_id and type = type - 1, then union all with the type 3 rows.

SELECT x.*, y.NAME as upper_name
FROM tbl_1 x
    inner join tbl_1 y on x.UPPER_ID = y.ENTRY_ID and x.TYPE = y.TYPE - 1
WHERE x.TYPE IN (1,2)
UNION ALL
SELECT *, NULL AS upper_name
FROM TBL_1
WHERE type = 3;
  • Related