我在MySQL中具有以下信息的SQL表:
id | prev | next
1 | 7 | 2
2 | 1 | 3
3 | 2 | 6
4 | 6 | 5
5 | 4 | null
6 | 3 | 4
7 | null | 1
我想使用SQL查询来按升序将其按下一列或按上一列的降序进行排序,其中next是指向下一行的指针,previous是指向上一行的指针,因此,例如,如果我想按升序排序得到的结果如下:
id | prev | next
7 | null | 1
1 | 7 | 2
2 | 1 | 3
3 | 2 | 6
6 | 3 | 4
4 | 6 | 5
5 | 4 | null
那怎么办?
更新:第一个表按id排序,但是我想以获取第二个表的方式对其进行排序,第二个表是通过下一个值生成的,所以第一行是7(id = 7)因为prev为null,第二个为1,因为第一行的下一列为1,然后第三行为2,因为2是第二行的下一列的值,依此类推。
答案 0 :(得分:1)
嗨,我找到了一个有解决方案的程序。 当我有这样的桌子时:
CREATE TABLE `zz_test` (
`id` int(11) NOT NULL,
`prev` int(11) DEFAULT NULL,
`next` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
和记录:
INSERT INTO `zz_test` VALUES ('1', '7', '2');
INSERT INTO `zz_test` VALUES ('2', '1', '3');
INSERT INTO `zz_test` VALUES ('3', '2', '6');
INSERT INTO `zz_test` VALUES ('4', '6', '5');
INSERT INTO `zz_test` VALUES ('5', '4', null);
INSERT INTO `zz_test` VALUES ('6', '3', '4');
INSERT INTO `zz_test` VALUES ('7', null, '1');
可以通过以下过程对其进行排序:
DROP PROCEDURE IF EXISTS zz_sort_test;
CREATE PROCEDURE zz_sort_test()
BEGIN
DECLARE next_value INT DEFAULT 1;
DECLARE rows_count INT DEFAULT 0;
DECLARE iterations INT DEFAULT 0;
DECLARE cid, cnext, cprev INT DEFAULT NULL;
DROP TEMPORARY TABLE IF EXISTS sorted;
CREATE TEMPORARY TABLE IF NOT EXISTS sorted (iter INT, id INT, prev INT, next INT);
SELECT COUNT(1) INTO rows_count FROM zz_test;
#first row
SELECT next INTO next_value FROM zz_test WHERE prev IS NULL LIMIT 1;
SELECT id, prev, next INTO cid, cprev, cnext FROM zz_test WHERE next_value = next;
INSERT INTO sorted (iter, id, prev, next) VALUES (-1, cid, cprev, cnext);
loopy: LOOP
SET iterations = iterations + 1;
IF rows_count = iterations THEN
LEAVE loopy;
END IF;
SELECT id, prev, next INTO cid, cprev, cnext FROM zz_test WHERE next_value = id;
SET next_value := cnext;
INSERT INTO sorted (iter, id, prev, next) VALUES (iterations, cid, cprev, cnext);
END LOOP loopy;
SELECT id, prev, next FROM sorted ORDER BY iter;
END
解释那里发生的事情:
您可以通过以下方式调用它:
call zz_sort_test;
我使用mysql 5.7.18
对其进行了测试编辑: 我编辑了答案,因此第一个选定的行将是 prev value = NULL的行 我添加了LIMIT 1,用于prev = NULL的行多于一个的情况