Home > Blockchain >  Setting ParentID's
Setting ParentID's

Time:09-30

I have a table:

ID Desc ParentID
1 Test A 0
2 Test A 0
3 Test A 0
4 Test B 0
5 Test B 0
6 Test B 0

I need help with an SQL Update Script that will take the first distinct Desc, keep the parentID of 0, but make all other instances of the Desc have a ParentID of the first.

So, by the end, it will be:

Sample Result Data:

1 Test A 0
2 Test A 1
3 Test A 1
4 Test B 0
5 Test B 4
6 Test B 4

CodePudding user response:

Desc is a reserved word so it is a bad choice, the rest can be solved with a cte to get the parent of all Desc

WITH CTE as (
  SELECT MIN(ID) min_id, [Desc] FROM TableA GROUP BY [Desc])
SELECT [ID], ta.[Desc], CASE WHEN ID = min_id THEN ParentID ELSE min_id END as ParentID 
  FROM TableA ta JOIN CTE ON ta.[Desc] = CTE.[Desc]
ID Desc ParentID
1 Test A 0
2 Test A 1
3 Test A 1
4 Test B 0
5 Test B 4
6 Test B 4

fiddle

An Update is actually also easy

WITH CTE as (
  SELECT MIN(ID) min_id, [Desc] FROM TableA GROUP BY [Desc])
, CTE2 AS (SELECT [ID], CASE WHEN ID = min_id THEN ParentID ELSE min_id END as ParentID 
  FROM TableA ta JOIN CTE ON ta.[Desc] = CTE.[Desc])
UPDATE TableA SET ParentID =  (SELECT ParentID FROM CTE2 WHERE ID = TableA.ID)
6 rows affected
SELECT * FROM TableA
ID Desc ParentID
1 Test A 0
2 Test A 1
3 Test A 1
4 Test B 0
5 Test B 4
6 Test B 4

fiddle

CodePudding user response:

You can do this without any self-joins, using a window function

WITH cte AS (
    SELECT *,
      MIN(a.ID) OVER (PARTITION BY a.[Desc]) AS min_id
    FROM TableA a
)
UPDATE cte
SET ParentId = min_id
WHERE ID <> min_id;
  • Related