【问题标题】:How to mak a recursive self join in MySQL如何在 MySQL 中进行递归自连接
【发布时间】:2015-07-01 18:11:06
【问题描述】:

我正在建立一个需要生成收集列表的网上商店。 问题是我有 3 种产品和一个递归表(无限)。 即产品、选项和类别,类别是递归的。

我正在尝试使用字段Order.idOrderProduct.productComponent.id 构建视图。

在这里你可以看到我已经看到的内容,但是我删除了 -- by 选项的部分,因为它不会“提供”示例。

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`

我的表格类别如下所示:

  • id - 很明显
  • 标签 - 另一个表中名称的 ID
  • 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 中的黑魔法。除非您绝对别无选择,否则不要使用它们。改为在客户端进行递归。
  • 我不像@Quassnoi 那样对会话变量过敏,但即使是我也会犹豫。在这么多不同的子句中使用同一个子句通常是一个非常非常非常糟糕的主意。
  • 我也读过,但因为我使用视图,所以我看不到其他选择。 (如果它可以在视图中工作)。

标签: mysql join recursion view


【解决方案1】:

没有真正的方法(至少我知道)在 MySQL 中进行“递归”连接。如果您有这样的表结构,我所知道的最佳解决方案是使用存储过程来循环和“收集”相关行和/或构建“路径”;不幸的是,您无法加入存储过程的结果,因此这通常意味着将数据放入预先确定的临时表中,以便在过程执行后使用。

或者,您可以在代码中分析递归表以确定其当前“深度”,以便以编程方式组合查询。

【讨论】:

  • 我不得不承认我从未研究过存储过程,也不知道它们是如何工作的。但从我现在发现的情况来看,似乎不允许在视图中使用存储过程。此外,深度可能会有所不同,其中没有静态深度,不是现在也不是将来,很遗憾。
  • 因此每次都以编程方式确定深度。不,您不能在视图中使用存储过程,但它可以返回结果集; Ii 一种行为类似于视图的感觉,但不具备 JOINed、WHEREd 等功能。但是,您可以使用存储过程的参数来重现类似的功能(难度不同)。
  • @IMarks,同样,我从未尝试过,但可以使用存储过程根据需要实际动态创建(和重新创建)视图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 1970-01-01
  • 2017-05-28
相关资源
最近更新 更多