I need to order rows in my SQL Server table:
| StateID | NextStateID | Description |
|---|---|---|
| 874 | 2 | A |
| 1631 | 3 | B |
| 935 | 344 | C |
| 907 | 813 | D |
| 2 | 814 | E |
| 813 | 874 | F |
| 1 | 907 | G |
| 814 | 935 | H |
| 344 | 1631 | I |
Into the table:
| StateID | NextStateID | Description |
|---|---|---|
| 1 | 907 | G |
| 907 | 813 | D |
| 813 | 874 | F |
| 874 | 2 | A |
| 2 | 814 | E |
| 814 | 935 | H |
| 935 | 344 | C |
| 344 | 1631 | I |
| 1631 | 3 | B |
As you can see, the algorithm is as follows: starting from StateID = 1, you need to look at the value of the column NextStateID and put the row in which StateID = NextStateID after the previous row. And so, as long as there are such StateID.
Data:
DECLARE @t TABLE
(
StateID int,
NextStateID int,
Description varchar(255)
)
INSERT INTO @t
VALUES (874, 2, 'A'),
(1631, 3, 'B'),
(935, 344, 'C'),
(907, 813, 'D'),
(2, 814, 'E'),
(813, 874, 'F'),
(1, 907, 'G'),
(814, 935, 'H'),
(344, 1631, 'I')
SELECT * FROM @t
I would be happy to get your suggestions.
CodePudding user response:
The easiest way is to use a recursrve CTE
declare @t table(
StateID int,
NextStateID int,
Description varchar(255)
);
insert into @t values (874, 2, 'A'),
(1631, 3, 'B'),
(935, 344, 'C'),
(907, 813, 'D'),
(2, 814, 'E'),
(813, 874, 'F'),
(1, 907, 'G'),
(814, 935, 'H'),
(344, 1631, 'I');
WITH CTE AS
(select 0 as level, StateID,NextStateID,Description from @t
WHERE StateID = 1
UNION ALL
SELECT
level 1,
e.StateID,e.NextStateID,e.Description
FROM
@t e
INNER JOIN CTE o
ON o.NextStateID = e.StateID
)
SELECT StateID,NextStateID,Description FROM CTE
ORDER BY level
| StateID | NextStateID | Description |
|---|---|---|
| 1 | 907 | G |
| 907 | 813 | D |
| 813 | 874 | F |
| 874 | 2 | A |
| 2 | 814 | E |
| 814 | 935 | H |
| 935 | 344 | C |
| 344 | 1631 | I |
| 1631 | 3 | B |
