[英]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,即Previous
和Next
列所引用的。
我现在想要的是编写一个SELECT *语句,它将按Previous
和Next
字段排序所有结果。 undefined
值标记结束元素。 我怎么能实现这一目标? 在该表的情况下,上述表现,我想要的顺序是什么所示的,随着最后2个位置交换,所以Next
行X点到Y行的UID,具有Previous
指向UID排X.等
您要创建的是递归查询。 不幸的是,MySQL并没有让这很容易。 如果父母的索引总是大于孩子,那么有相对简单的解决方案,但这不是这种情况。 讨论这类问题有几个问题。 以下问题的答案探讨了尝试此类查询的不同方法,包括使用存储过程。
继续使用存储过程的想法,您可以尝试以下方法:
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
;
所以,当Previous
为NULL
你把它放在-1以确保他是列表中的第一个,当Next
为NULL
你把它放在一个非常高的值,以确保它将是列表中的最后一个...然后你只是必须按Previous
和Next
排序查询。
我必须强调,这个解决方案专注于呈现的数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.