0

我有以下数据:

                id                  parent_id           
                ------------------  ------------------  
                Editor              null
                Printer             Editor
                TextWritingProggie  Printer
                LaTeX               TextWritingProggie
                OOfficeWriter       TextWritingProggie
                PhoneBook           TextWritingProggie

我正在查询电话簿 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

任何帮助都会很棒

4

1 回答 1

0

一些 RDBMS 产品提供内置的分层查询。例如,Oracle SQL 有一种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) |

CONNECT BY PRIOR id = parent_id在 Oracle 分层查询中编码的逻辑在此处显示为重复操作的重复ON子句。LEFT JOIN

于 2015-02-25T03:10:09.473 回答