Last active
June 5, 2020 20:13
-
-
Save estum/0439def37ae45d4e08897755e754613e to your computer and use it in GitHub Desktop.
PostgreSQL: recursively shift rows in order using modifier
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- +--------+-------+-------+ | |
-- | init | mod | exp | | |
-- |--------+-------+-------| | |
-- | 6 | -1 | 5 | | |
-- | 5 | 0 | 4 | | |
-- | 4 | 1 | 6 | | |
-- | 3 | 0 | 3 | | |
-- | 2 | -1 | 1 | | |
-- | 1 | 0 | 2 | | |
-- +--------+-------+-------+ | |
WITH v(init, mod, exp) AS ( | |
VALUES (6, -1, 5), (5, 0, 4), (4, 1, 6), (3, 0, 3), (2, -1, 1), (1, 0, 2) | |
), sort_r(init, pos) AS ( | |
WITH RECURSIVE t(init, mod, exp, pos, d) AS ( | |
SELECT *, init, 1 FROM v | |
UNION ALL | |
SELECT t.init, | |
t.mod - (lag(t.mod) OVER w), | |
t.exp, | |
t.pos + t.mod, | |
t.d + 1 | |
FROM t | |
WHERE t.mod <> 0 | |
WINDOW w AS (ORDER BY t.pos DESC ROWS 1 PRECEDING) | |
) | |
SELECT init, row_number() OVER (ORDER BY pos ASC) | |
FROM (SELECT * FROM t WHERE d = (SELECT max(d) FROM t t2 WHERE t2.init = t.init)) sub | |
) | |
SELECT sort_r.*, v.exp FROM sort_r, v WHERE v.init = sort_r.init ORDER BY pos DESC; | |
-- +--------+-------+-------+ | |
-- | init | pos | exp | | |
-- |--------+-------+-------| | |
-- | 4 | 6 | 6 | | |
-- | 6 | 5 | 5 | | |
-- | 5 | 4 | 4 | | |
-- | 3 | 3 | 3 | | |
-- | 1 | 2 | 2 | | |
-- | 2 | 1 | 1 | | |
-- +--------+-------+-------+ | |
-- | |
-- \ 0 / |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment