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 |
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 |
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;