In case you need only one level of depth, you can do it like this:
SELECT CONCAT(CASE WHEN parent IS NOT NULL THEN '- ' ELSE '' END, name), age
FROM table
ORDER BY
CASE WHEN parent IS NOT NULL THEN parent ELSE id END, parent IS NOT NULL
If you want to build the whole hierarchy, it's harder.
Update: Initially, the question tag said MySQL
, so the answer is relevant to MySQL
.
I'll leave the answer, but it won't work for SQLite
.
MySQL
does not have native support for this, so you'll need to create some special functions.
See this article in my blog for details:
In a nutshell:
CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE _id INT;
DECLARE _parent INT;
DECLARE _next INT;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;
SET _parent = @id;
SET _id = -1;
IF @id IS NULL THEN
RETURN NULL;
END IF;
LOOP
SELECT MIN(id)
INTO @id
FROM t_hierarchy
WHERE parent = _parent
AND id > _id;
IF @id IS NOT NULL OR _parent = @start_with THEN
SET @level = @level + 1;
RETURN @id;
END IF;
SET @level := @level - 1;
SELECT id, parent
INTO _id, _parent
FROM t_hierarchy
WHERE id = _parent;
END LOOP;
END
SELECT CONCAT(REPEAT(' ', level - 1), CAST(hi.id AS CHAR)) AS treeitem, parent, level
FROM (
SELECT hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
FROM (
SELECT @start_with := 0,
@id := @start_with,
@level := 0
) vars, t_hierarchy
WHERE @id IS NOT NULL
) ho
JOIN t_hierarchy hi
ON hi.id = ho.id