按下一个和上一个订购

问题描述 投票:2回答:1

我在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查询来命令它按下一列递增或按prev列降序,其中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是第二行的下一列的值,依此类推。

mysql sql sql-order-by
1个回答
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

解释那里发生的事情:

  • 它创建临时表来存储所选数据(已排序)
  • 从z测试表中选择行数(行数)
  • 选择minimal(without null)下一个值(next_value)并将其中的行插入临时表
  • 在循环中保存next_value以供下一次迭代搜索
  • 和知道何时停止的迭代次数(迭代次数)
  • 使用迭代计数器插入临时表中的行,因为最后它将有助于排序
  • 最后,简单的返回所有从临时表中排序

你可以叫它:

call zz_sort_test;

我用mysql 5.7.18测试了它

编辑:我编辑了答案,所以第一个选中的行将是一个前置值= NULL我添加LIMIT 1的情况下,将有多个行与prev = NULL

© www.soinside.com 2019 - 2024. All rights reserved.