我有一个表格,其中产品根据层次关系进行分类,如树形结构。我必须在任何级别选择一个类别和所有子类别。见下图:
例如,我想要一个 sql 语句,当我查询传递 id=11 时,它返回我 (19,20,21,22,23,24,25,26)
在 MySQL 中存储分层数据有几种不同的方法。查看 Bill Karwin 的演示文稿,其中演示了四个选项。
您正在使用邻接列表模型来存储分层数据,但不幸的是,这是您可以选择用于查询子树的最难的模型。
您的选择是:
SELECT * FROM `Products`
WHERE parentId IN (
SELECT id FROM `Products`
WHERE parentId = 11)
注意:如果您的层次结构深于 2 个级别,这将不起作用。
您能否稍微更改您的数据结构以包含计算的 linage 列。有一篇很棒的文章向您展示了通用概念(忽略数据库类型)。
基本上,您计算的 linage 列应包含其中的父母列表,例如
第 26 项将包含\11\
如果你有一个子项目,你可以有
\11\subitem\
然后你可以简单地对你的 linage 表做一个类似的检查,它比迭代搜索快得多,你可以使用存储的过程或触发器来创建它。
Node ParentNode EmployeeID Depth Lineage
100 NULL 1001 0 /
101 100 1002 1 /100/
102 101 1003 2 /100/101/
103 102 1004 3 /100/101/102/
104 102 1005 3 /100/101/102/
105 102 1006 3 /100/101/102/
这很麻烦,你必须做 n 个联合,其中 n 是你的层次结构有多深,但它应该可以工作:
SELECT * FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId = 11)
UNION
SELECT * FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId = 11))
UNION
SELECT * FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId IN (
SELECT id FROM `Products` WHERE parentId = 11)))