我有一张这样的表:
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行位置交换,因此行X的Next
指向行Y的UID ,其Previous
指向行X的UID等。
答案 0 :(得分:2)
您尝试创建的是递归查询。不幸的是,MySQL并没有让这很容易。如果父母的索引总是大于孩子,那么有相对简单的解决方案,但这不是这种情况。讨论这类问题有几个问题。以下问题的答案探讨了尝试此类查询的不同方法,包括使用存储过程。
How to do the Recursive SELECT query in 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;
然后,您可以调用存储过程以按顺序检索表。
答案 1 :(得分:0)
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&lt;下一个 - 是否一定如此?似乎任意链接可能无法保持这一点。如果您需要next
根据UniqueId
加载下一行,则代码要复杂得多。
答案 2 :(得分:0)
我认为这个要求缺乏细节。
但是,您希望最终结果是这样的吗?
+----------+-----------+-----------+
| 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
订购查询。
我必须强调,这个解决方案专注于提供的数据。