Skip to content

Instantly share code, notes, and snippets.

@knoxknox
Last active December 29, 2019 23:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knoxknox/13d763277a88e89016779a495202a66a to your computer and use it in GitHub Desktop.
Save knoxknox/13d763277a88e89016779a495202a66a to your computer and use it in GitHub Desktop.
##
# MySQL 8 CTE
# tree (id int, pid int, name varchar(255))
#
WITH recursive tbl AS (
SELECT
t.id,
1 AS depth,
cast(name as CHAR(500)) AS path
FROM tree t WHERE t.pid IS NULL
UNION
SELECT
c.id,
tbl.depth + 1,
concat(tbl.path, ' / ', c.name)
FROM tree c JOIN tbl ON tbl.id = c.pid
)
SELECT id, depth, path FROM tbl ORDER by path;
##
# The same with code.
# list => [id, name, pid]
#
list = [
[15, 'category15', 0],
[16, 'category16', 15],
[19, 'category19', 0],
[20, 'category20', 19],
[21, 'category21', 20],
[22, 'category22', 21],
[23, 'category23', 19],
[24, 'category24', 21],
[25, 'category25', 22],
[26, 'category26', 22],
[27, 'category27', 25],
[30, 'category30', 16],
]
def index_by_id(list)
result = {}
list.each do |el|
id = el[0]
name = el[1]
parent_id = el[2]
result[id] = { name: name, parent_id: parent_id }
end
result
end
def traverse(list)
result = {}
index = index_by_id(list)
list.each do |el|
id = el[0]
name = el[1]
parent_id = el[2]
result[id] = []
if parent_id == 0
result[id] << name
else
path = []
while parent_id != 0
path.unshift(name)
name = index[parent_id][:name]
parent_id = index[parent_id][:parent_id]
end
path.unshift(name)
result[id] << path.join(' / ')
end
end
result
end
puts traverse(list).inspect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment