如何在 MySQL 中进行递归自连接
How to mak a recursive self join in MySQL
我正在建立一个需要生成收集列表的网上商店。
问题是我有 3 种产品和递归 table(无限)。
即Products、Option和Category,类别的是递归的。
我正在尝试使用字段 Order.id
、OrderProduct.product
、Component.id
.
构建视图
在这里您可以看到我已经看到的内容,但是我删除了 -- by option 的部分,因为它不是 'feed' 示例。
CREATE VIEW `Gatherlist` as
SELECT `O`.`id`, `OP`.`product`, `C`.`id` FROM `Order` `O` -- By Product
LEFT JOIN `OrderProduct` `OP`
ON `O`.`id` = `OP`.`order`
LEFT JOIN `Product` `P`
ON `OP`.`product` = `P`.`id`
LEFT JOIN `ProductComponent` `PC`
ON `P`.`id` = `PC`.`product`
LEFT JOIN `Component` `C`
ON `PC`.`component` = `C`.`id`
UNION ALL
SELECT `O`.`id`, `OP`.`product`, `C`.`id` FROM `Order` `O` -- By Category
LEFT JOIN `OrderProduct` `OP`
ON `O`.`id` = `OP`.`order`
LEFT JOIN `Product` `P`
ON `OP`.`product` = `P`.`id`
-- LEFT JOIN `Category` `PC`
-- ON `P`.`category` = `PC`.`id`
-- Here should start a recursive join on Category
INNER JOIN (
SELECT group_concat(@id :=
(
SELECT id
FROM `Category`
WHERE parent = @id
)
) AS categoryTemp
FROM (
SELECT @id := 1
) vars
STRAIGHT_JOIN
`Category`
WHERE @id IS NOT NULL
) as `PC` on `P`.`category` = `PC`.`id`
-- And it will end somewhere again (i hope)
LEFT JOIN `CategoryCompenent` `CC`
ON `PC`.`id` = `CC`.`category`
LEFT JOIN `Component` `C`
ON `CC`.`component` = `C`.`id`
ORDER BY `O`.`id`, `OP`.`product`, `C`.`id`
我的 table 类别如下所示:
- id - 显而易见
- label - 另一个名称的 id table
- parent - 上面铺设的Category的id
我找到了这个,但无法弄清楚如何将它放入联接中(在具有联合的视图中)。
SELECT group_concat(@id :=
(
SELECT id
FROM comments
WHERE parent_id = @id
)) AS comment
FROM (
SELECT @id := 1
) vars
STRAIGHT_JOIN
comments
WHERE @id IS NOT NULL
没有真正的方法(至少我知道)在 MySQL 中进行 "recursive" 加入。如果你有这样一个 table 结构,我知道的最好的解决方案是使用存储过程循环和 "collect" 相关行 and/or build "paths";不幸的是,您无法加入存储过程的结果,因此这通常意味着让它将该数据放入预定的温度 table 以在过程执行后使用。
或者,您可以分析代码中的递归 table 以确定其当前 "depth",以便以编程方式编写查询。
我正在建立一个需要生成收集列表的网上商店。 问题是我有 3 种产品和递归 table(无限)。 即Products、Option和Category,类别的是递归的。
我正在尝试使用字段 Order.id
、OrderProduct.product
、Component.id
.
在这里您可以看到我已经看到的内容,但是我删除了 -- by option 的部分,因为它不是 'feed' 示例。
CREATE VIEW `Gatherlist` as
SELECT `O`.`id`, `OP`.`product`, `C`.`id` FROM `Order` `O` -- By Product
LEFT JOIN `OrderProduct` `OP`
ON `O`.`id` = `OP`.`order`
LEFT JOIN `Product` `P`
ON `OP`.`product` = `P`.`id`
LEFT JOIN `ProductComponent` `PC`
ON `P`.`id` = `PC`.`product`
LEFT JOIN `Component` `C`
ON `PC`.`component` = `C`.`id`
UNION ALL
SELECT `O`.`id`, `OP`.`product`, `C`.`id` FROM `Order` `O` -- By Category
LEFT JOIN `OrderProduct` `OP`
ON `O`.`id` = `OP`.`order`
LEFT JOIN `Product` `P`
ON `OP`.`product` = `P`.`id`
-- LEFT JOIN `Category` `PC`
-- ON `P`.`category` = `PC`.`id`
-- Here should start a recursive join on Category
INNER JOIN (
SELECT group_concat(@id :=
(
SELECT id
FROM `Category`
WHERE parent = @id
)
) AS categoryTemp
FROM (
SELECT @id := 1
) vars
STRAIGHT_JOIN
`Category`
WHERE @id IS NOT NULL
) as `PC` on `P`.`category` = `PC`.`id`
-- And it will end somewhere again (i hope)
LEFT JOIN `CategoryCompenent` `CC`
ON `PC`.`id` = `CC`.`category`
LEFT JOIN `Component` `C`
ON `CC`.`component` = `C`.`id`
ORDER BY `O`.`id`, `OP`.`product`, `C`.`id`
我的 table 类别如下所示:
- id - 显而易见
- label - 另一个名称的 id table
- parent - 上面铺设的Category的id
我找到了这个,但无法弄清楚如何将它放入联接中(在具有联合的视图中)。
SELECT group_concat(@id :=
(
SELECT id
FROM comments
WHERE parent_id = @id
)) AS comment
FROM (
SELECT @id := 1
) vars
STRAIGHT_JOIN
comments
WHERE @id IS NOT NULL
没有真正的方法(至少我知道)在 MySQL 中进行 "recursive" 加入。如果你有这样一个 table 结构,我知道的最好的解决方案是使用存储过程循环和 "collect" 相关行 and/or build "paths";不幸的是,您无法加入存储过程的结果,因此这通常意味着让它将该数据放入预定的温度 table 以在过程执行后使用。
或者,您可以分析代码中的递归 table 以确定其当前 "depth",以便以编程方式编写查询。