Mysql 在邻接列表/闭包表中查找最终重写id的SQL查询

Mysql 在邻接列表/闭包表中查找最终重写id的SQL查询,mysql,sql,adjacency-list,transitive-closure-table,Mysql,Sql,Adjacency List,Transitive Closure Table,我有一个名为attribute的邻接列表表(它还有一个名为attribute\u closure的闭包表,映射后便于递归) 属性表中的每个条目都是4种层次结构类型中的一种,每种类型都可以继承和覆盖其父类型的条目。按层次结构,这四种可能的类型是,类别,产品线,产品,型号。因此,category定义了一个属性树,product\u line继承并可以在任何时候覆盖,product和model依此类推 这是预先存在的应用程序的预先存在的结构,因此任何重构建议都无法使用:-) 因此,邻接列表属性具有以下

我有一个名为
attribute
的邻接列表表(它还有一个名为
attribute\u closure
的闭包表,映射后便于递归)

属性
表中的每个条目都是4种层次结构类型中的一种,每种类型都可以继承和覆盖其父类型的条目。按层次结构,这四种可能的类型是,
类别
产品线
产品
型号
。因此,
category
定义了一个属性树,
product\u line
继承并可以在任何时候覆盖,
product
model
依此类推

这是预先存在的应用程序的预先存在的结构,因此任何重构建议都无法使用:-)

因此,邻接列表
属性
具有以下列:
id、父项id、覆盖项id
,其中
覆盖项id
(如果设置)是对
属性.id
的引用,与
父项id
相同。 如果设置了
overrides\u id
parent\u id
将始终与被重写属性的
parent\u id
的值相匹配

对于每个层次结构类型,都有一个支持表将类型映射到属性,即-
category\u id,attribute\u id

我需要能够获得完整的属性树,并尊重所有覆盖。

示例数据(此特定示例仅适用于产品级别,但您已经了解了想法)。请根据需要使用您自己的样本数据进一步充实

属性

+-------+-----------+--------------+
|   id  | parent_id | overrides_id |
+-------+-----------+--------------+
|  6036 |      5931 |         NULL |
|  6069 |      5931 |         6036 |
| 30955 |      5931 |         6069 |
+-------+-----------+--------------+
+-------------+--------------+
| category_id | attribute_id |
+-------------+--------------+
|           2 |         6036 |
+-------------+--------------+
+-----------------+--------------+
| product_line_id | attribute_id |
+-----------------+--------------+
|              16 |         6069 |
+-----------------+--------------+
+------------+--------------+
| product_id | attribute_id |
+------------+--------------+
|         69 |        30955 |
+------------+--------------+
category\u属性

+-------+-----------+--------------+
|   id  | parent_id | overrides_id |
+-------+-----------+--------------+
|  6036 |      5931 |         NULL |
|  6069 |      5931 |         6036 |
| 30955 |      5931 |         6069 |
+-------+-----------+--------------+
+-------------+--------------+
| category_id | attribute_id |
+-------------+--------------+
|           2 |         6036 |
+-------------+--------------+
+-----------------+--------------+
| product_line_id | attribute_id |
+-----------------+--------------+
|              16 |         6069 |
+-----------------+--------------+
+------------+--------------+
| product_id | attribute_id |
+------------+--------------+
|         69 |        30955 |
+------------+--------------+
产品线属性

+-------+-----------+--------------+
|   id  | parent_id | overrides_id |
+-------+-----------+--------------+
|  6036 |      5931 |         NULL |
|  6069 |      5931 |         6036 |
| 30955 |      5931 |         6069 |
+-------+-----------+--------------+
+-------------+--------------+
| category_id | attribute_id |
+-------------+--------------+
|           2 |         6036 |
+-------------+--------------+
+-----------------+--------------+
| product_line_id | attribute_id |
+-----------------+--------------+
|              16 |         6069 |
+-----------------+--------------+
+------------+--------------+
| product_id | attribute_id |
+------------+--------------+
|         69 |        30955 |
+------------+--------------+
产品属性

+-------+-----------+--------------+
|   id  | parent_id | overrides_id |
+-------+-----------+--------------+
|  6036 |      5931 |         NULL |
|  6069 |      5931 |         6036 |
| 30955 |      5931 |         6069 |
+-------+-----------+--------------+
+-------------+--------------+
| category_id | attribute_id |
+-------------+--------------+
|           2 |         6036 |
+-------------+--------------+
+-----------------+--------------+
| product_line_id | attribute_id |
+-----------------+--------------+
|              16 |         6069 |
+-----------------+--------------+
+------------+--------------+
| product_id | attribute_id |
+------------+--------------+
|         69 |        30955 |
+------------+--------------+
查询包含上述属性的树时,应仅返回属性id
30955
,因为显示的其他两个属性应在30955之前过时


如前所述,我还有一个典型的闭包表,它映射出
祖先
后代
级别
。如果您可以包含一个使用闭包返回覆盖生效的树的结果,则会得到额外的分数。:-)

我最终采用的解决方案是构建第二个闭包表,该表表示覆盖的层次结构(类似于基于父对象id构建闭包,但使用覆盖对象id)。这样,我就可以查询任何给定属性的整个覆盖层次结构

我本来希望找到一个查询来结束它们,但是使用第二个闭包表更简单,性能更好,等等