我有一个MySQL表,如下所示:
> describe books;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(255) | YES | | NULL | |
| after | int(11) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
现在,我想从表中选择所有行,但是作为已排序的链表。 after
是查询结果中应该出现的id
行。当然,我可以在使用此表的脚本中查询后执行此操作,但我想知道是否有办法以这种方式对行进行排序。
表格中的数据示例:
(1, "title #1", 0)
(2, "title #2", 3)
(3, "title #3", 1)
(4, "title #4", 2)
预期结果:
(1, "title #1", 0)
(3, "title #3", 1)
(2, "title #2", 3)
(4, "title #4", 2)
答案 0 :(得分:2)
如果对于所有行,您的after
值比id
值更小(或更大),则发布的ORDER BY
解决方案将会执行。
如果没有,您将需要迭代地遍历after-> id关系,并且原始SQL根本不支持此。现代SQL允许您在SELECT
子句中执行此操作,例如Oracle有CONNECT BY
,而recursive subqueries也可以。 MySQL显然没有等价物。
另一种方法是在the procedural language you can wrap around SQL queries中进行迭代,就像在the article Skrol29 links to中一样。
然而,无论你如何执行,这次迭代总是很慢。
另一种方法是重新设计您在数据库中表示此关系的方式 - 参见例如nested set model。
答案 1 :(得分:1)
你不能在mysql中做这个标准,你可以编写像
这样的东西Select * from books b_root
Left join books as b_child1 ON b_root.after = b_child1.id
Left join books as b_child2 ON b_child1.after = b_child2.id
Where b_root.after = 0
你会得到类似的东西 (1,“标题#1”,0,3,“标题#3”,1,2,“标题#2”,3)
那是3深 或者尝试用脚本或编程语言链接它解决此问题的python脚本示例
books = [
{'id':1, 'title' :"title #1", 'after':0},
{'id':2, 'title' :"title #2", 'after':3},
{'id':3, 'title' :"title #3", 'after':1},
{'id':4, 'title' :"title #4", 'after':2},]
def recursive(book):
global books
for i in books:
if book['id'] == i['after']:
print i
recursive(i)
for i in books:
if i['after'] == 0:
print i
recursive(i)
答案 2 :(得分:1)
SELECT * FROM my_table ORDER BY after;
不起作用。所描述的问题就像一个人的队列,每个人都只知道前面的单身人士。
恕我直言,最好的方法是有一个单独的排序表来表示队列:
> describe books_order;
+---------------+--------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+---------------+--------------+------+-----+---------+
| order_no | int(11) | NO | | |
| books_id | int(11) | NO | | |
+---------------+--------------+------+-----+---------+
SELECT * FROM books WHERE id = (SELECT books_id FROM books_order ORDER BY order_no);
答案 3 :(得分:1)
这实际上是一个分层查询问题。 实际上,您需要对行进行排序,考虑到每行对于父行具有“child_row.after = parent_row.id”的行。
如果您的层次结构只有一个级别,则可以使用简单查询完成。 如果你的层次结构有一个免费的级别,那么解决它是非常困难的,因为MySQL没有分层功能。
但这是一篇解决问题的文章:
http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/
答案 4 :(得分:0)
有这个表:
create table list(id int primary key not null, previous int, description varchar(10));
您可以通过以下方式获取元素:
select l2.* from (select @r as _parent, @r := (select id from list where previous = _parent) as id, @n := @n + 1 as n from (select @r := 0, @n := 0) vars, list) k, list l2 where k.id = l2.id order by n;
答案 5 :(得分:-3)