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 |
+------------+--------------+
查询包含上述属性的树时,应仅返回属性id30955
,因为显示的其他两个属性应在30955之前过时
如前所述,我还有一个典型的闭包表,它映射出
祖先
,后代
,级别
。如果您可以包含一个使用闭包返回覆盖生效的树的结果,则会得到额外的分数。:-) 我最终采用的解决方案是构建第二个闭包表,该表表示覆盖的层次结构(类似于基于父对象id构建闭包,但使用覆盖对象id)。这样,我就可以查询任何给定属性的整个覆盖层次结构
我本来希望找到一个查询来结束它们,但是使用第二个闭包表更简单,性能更好,等等