繁体   English   中英

MySQL SELECT顺序的值为2列

[英]MySQL SELECT order by values of 2 columns

我有这样一张桌子:

CREATE TABLE rows(
    UniqueID VARCHAR(225),
    Previous VARCHAR(225),
    Next VARCHAR(225)
);

对于内容,看起来像这样:

+----------+-----------+-----------+
| UniqueID | Previous  | Next      |
+----------+-----------+-----------+
|    676   | undefined |       219 |
|    890   |       219 | undefined |
|    219   |       676 |       890 |
+----------+-----------+-----------+

如您所见,这些行具有UID,即PreviousNext列所引用的。

我现在想要的是编写一个SELECT *语句,它将按PreviousNext字段排序所有结果。 undefined值标记结束元素。 我怎么能实现这一目标? 在该表的情况下,上述表现,我想要的顺序是什么所示的,随着最后2个位置交换,所以Next行X点到Y行的UID,具有Previous指向UID排X.等

您要创建的是递归查询。 不幸的是,MySQL并没有让这很容易。 如果父母的索引总是大于孩子,那么有相对简单的解决方案,但这不是这种情况。 讨论这类问题有几个问题。 以下问题的答案探讨了尝试此类查询的不同方法,包括使用存储过程。

如何在MySQL中进行递归SELECT查询?

继续使用存储过程的想法,您可以尝试以下方法:

CREATE PROCEDURE getInOrder()
  BEGIN
    DECLARE child_id VARCHAR(256);
    DECLARE prev_id VARCHAR(256);
    SELECT UniqueID INTO prev_id FROM rows WHERE Previous = 'undefined';
    SELECT `Next` INTO child_id
    FROM rows WHERE UniqueID = prev_id;
    CREATE TEMPORARY TABLE IF NOT EXISTS temp_table AS (SELECT * FROM rows WHERE 1=0);
    TRUNCATE TABLE temp_table;
    WHILE child_id <> 'undefined' DO
      INSERT INTO temp_table SELECT * FROM rows WHERE UniqueID = prev_id;
      SET prev_id = child_id;
      SELECT `Next` INTO child_id
      FROM rows WHERE UniqueID = prev_id;
    END WHILE;
    INSERT INTO temp_table SELECT * FROM rows WHERE UniqueID = prev_id;
    SELECT * FROM temp_table;
  END;

然后,您可以调用存储过程以按顺序检索表。

工作示例: http//sqlfiddle.com/#!9 / 0dec / 2

ORDER BY IFNULL(prev, ''),         -- some value lower than the rest
         IFNULL(next, 'zzzzz')     -- some value higher than all values

(在技术上,所述第一部分可以是简单地prev ,而不IFNULL 。)

如果id确实是数字,则应使用数字数据类型,例如INT UNSIGNED 如果他们真的是字符串,你需要225吗?

这假设prev <next - 是否一定如此? 似乎任意链接可能无法保持这一点。 如果您需要查看next一个基于UniqueId加载下一行,则代码要复杂得多。

我认为这个要求缺乏细节。

但是,你想最终的结果是这样的吗?

+----------+-----------+-----------+
| UniqueID | Previous  | Next      |
+----------+-----------+-----------+
|    676   | undefined |       219 |
|    219   |       676 |       890 |
|    890   |       219 | undefined |
+----------+-----------+-----------+

如果我是对的,你可以实现它(我将该表命名为demo ):

SELECT d.* FROM (
    SELECT UniqueID, IF(Previous IS NULL, -1, Previous) AS Previous, IF(Next   IS NULL, 999999999999, Next) as Next
    FROM demo
)t
JOIN demo d ON d.UniqueID = t.UniqueID
ORDER BY t.Next, t.Previous
;

所以,当PreviousNULL你把它放在-1以确保他是列表中的第一个,当NextNULL你把它放在一个非常高的值,以确保它将是列表中的最后一个...然后你只是必须按PreviousNext排序查询。

我必须强调,这个解决方案专注于呈现的数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM