I have a MySQL table looking like this:
> 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 | |
+---------------+--------------+------+-----+---------+----------------+
Now, I want to select all rows from the table, but as sorted linked list. after is an id of row it should be after in query result. Of course I could do that after query in my script using this table, but I’d like to know if there is a way to get the rows sorted in such way.
Example of data in table:
(1, "title #1", 0)
(2, "title #2", 3)
(3, "title #3", 1)
(4, "title #4", 2)
Expected result:
(1, "title #1", 0)
(3, "title #3", 1)
(2, "title #2", 3)
(4, "title #4", 2)
If for all rows, your
aftervalues are smaller (or all larger) than youridvalues, the postedORDER BYsolution will do.If not, you will need to traverse the after->id relation iteratively, and the original SQL does not support this at all. Modern SQLs do allow you to do this within a
SELECTclause, e.g. Oracle hasCONNECT BY, and recursive subqueries will do the trick as well. MySQL doesn’t apparently have an equivalent.An alternative is to do the iteration in the procedural language you can wrap around SQL queries, like in the article Skrol29 links to.
However, this iteration, regardless of how you perform it, will always be slow.
Another approach is to redesign the way in which you are representing this relationship in the database – see e.g. the nested set model.