我有以下数据:
id parent_id
------------------ ------------------
Editor null
Printer Editor
TextWritingProggie Printer
LaTeX TextWritingProggie
OOfficeWriter TextWritingProggie
PhoneBook TextWritingProggie
我正在查询PhoneBook id及其所有父母。它应该是一个层次结构,通向编辑器,因为他的父级为空,并且他通过打印机连接,打印机通过TextWritingProggie连接,然后连接到电话簿。
我认为使用SQL是更优选的,但可能需要通过PHP来处理。
这是我到目前为止所得到的,但它在不包含TextWritingProggie的记录后停止
SELECT * FROM acl_resources
WHERE id = 'TextWritingProggie' OR parent_id = 'TextWritingProggie'
ORDER BY COALESCE(parent_id, id), parent_id IS NOT NULL, id
任何帮助都会很棒
答案 0 :(得分:0)
一些RDBMS产品提供内置的分层查询。例如,Oracle SQL has一个START WITH ... CONNECT BY
语法,您可以使用此类查询来获取结果。
SELECT id, SYS_CONNECT_BY_PATH(parent_id, '/'), LEVEL -- Oracle
FROM res
WHERE id='PhoneBook'
CONNECT BY prior id=parent_id
ORDER BY LEVEL DESC
但不是MySQL。你必须以某种方式伪造它。一种方法是检索数据并在应用程序的内存中构建层次结构。
另一种方法是使用一系列LEFT JOIN
操作,这些操作比预期的层次结构深度更长。这个查询有点难看,但它确实有效。这种查询的每一行都包含该行的“族谱”。以下是您的数据示例(http://sqlfiddle.com/#!2/bab1d/4/0):
select a.id a, b.id b, c.id c, d.id d, e.id e, f.id f, g.id g /*MySQL*/
from res a
left join res b on a.parent_id = b.id
left join res c on b.parent_id = c.id
left join res d on c.parent_id = d.id
left join res e on d.parent_id = e.id
left join res f on e.parent_id = f.id
left join res g on f.parent_id = g.id
where a.id = 'PhoneBook'
此特定查询的结果是
| A | B | C | D | E | F | G |
|-----------|--------------------|---------|--------|--------|--------|--------|
| PhoneBook | TextWritingProggie | Printer | Editor | (null) | (null) | (null) |
在Oracle层次结构查询中编码为CONNECT BY PRIOR id = parent_id
的逻辑在此处显示为重复ON
操作的重复LEFT JOIN
子句。