【问题标题】:Nesting categories for MySQLMySQL 的嵌套类别
【发布时间】:2016-10-01 06:20:12
【问题描述】:

API 像这样返回类别:

[1] => Array
        (
            [category_id] => 14308
            [parent_id] => 14308
            [level] => 0
        )

    [2] => Array
        (
            [category_id] => 179836
            [parent_id] => 14308
            [level] => 1
        )

        [3] => Array
            (
                [category_id] => 230022
                [parent_id] => 179836
                [level] => 2
            )

我需要像这样将它们插入数据库中:

╔═════════════╦═══════════╗
║ category_id ║ parent_id ║
╠═════════════╬═══════════╣
║       14308 ║         0 ║
║      179836 ║     14308 ║
║      230022 ║    179836 ║
╚═════════════╩═══════════╝

...这很容易,但category_to_path 表很棘手,我似乎无法弄清楚。它需要是这样的:

╔═════════════╦═════════╦═══════╗
║ category_id ║ path_id ║ level ║
╠═════════════╬═════════╬═══════╣
║       14308 ║   14308 ║     0 ║
║      179836 ║   14308 ║     0 ║
║      179836 ║  179836 ║     1 ║
║      230022 ║   14308 ║     0 ║
║      230022 ║  179836 ║     1 ║
║      230022 ║  230022 ║     2 ║
╚═════════════╩═════════╩═══════╝

这是我目前所拥有的:

$path_ids;
for ($i=0; $i <= ($category->CategoryLevel-1); $i++) { 
// -1 cause the API returns a non zero-based level

  $path_ids[$i]['category_id'] = $category->CategoryID;

  if ($category->CategoryLevel-1 == $i) {
    $path_ids[$i]['path_id'] = $category->CategoryParentID[0];
  }
  elseif ($category->CategoryLevel-1) {
    // ?
  }

  $path_ids[$i]['level'] = $i;

}

【问题讨论】:

  • 一般来说,这可能需要递归查询才能找到所有路径。
  • 你知道表中最深的路径有多少层吗?
  • @TimBiegeleisen 3 最大

标签: php mysql


【解决方案1】:

我会在从 API 获取数组后尝试重写数组,使其看起来像这样:

[14308] => Array
(
    [parent_id] => 14308
    [level] => 0
)

[179836] => Array
(
    [parent_id] => 14308
    [level] => 1
)

[230022] => Array
(
    [parent_id] => 179836
    [level] => 2
)

当您从 API 获取数组时,您可以使用简单的 foreach 循环对其进行处理。

$arrayFromApi = apiCallToObtainData();    
$newArray = [];
foreach($arrayFromApi as $value){
    $newArray[$value['category_id']] = [
        $value['parent_id'], 
        $value=['level'],
    ];
}

现在您可以轻松访问父母,因此实现您所需要的应该不难。

【讨论】:

  • 重写 API 不是一种选择。
  • 我不是说重写API——你可以从API获取数组后重写。
【解决方案2】:

以下查询应为您提供类别和路径。它没有给出级别,因为您的原始数据缺少任何类型的行号。如果您想获得关卡,您可能需要使用一些动态 SQL。

我使用的策略是交叉连接类别,从而生成所有可能的起点和终点。它还会生成一些表不支持的路径。为了删除这些不需要的路径,我会根据子查询检查每个路径,以确保可以通过在 3 步或更短的时间内从类别遍历到路径来创建它。

SELECT t1.category_id AS category_id,
       t2.category_id AS path_id
FROM yourTable t1
CROSS JOIN yourTable t2
INNER JOIN
(
    SELECT t1.category_id AS category_id_1,
           t2.category_id AS category_id_2,
           t3.category_id AS category_id_3
    FROM yourTable t1
    LEFT JOIN yourTable t2
        ON t1.parent_id = t2.category_id
    LEFT JOIN yourTable t3
        ON t2.parent_id = t3.category_id
) t2
    ON t1.category_id = t2.category_id_1 AND
       t2.category_id IN (t2.category_id_1, t2.category_id_2, t2.category_id_3)
ORDER BY category_id,
         path_id

【讨论】:

  • 描述中的 PHP 代码是我从 API 中获得的,然后我将其存储在一个数组中以一次性写入 DB,但我还不能以编程方式插入行,这就是问题所在。
  • 那么您是说您已经生成了category_to_path 表?
  • 是的,它是 OpenCart 电子商务软件。 stackoverflow.com/questions/15162193/… 所以表存在,我只需要使用 API 中的数据填充它们
  • 我现在不能对你的问题投反对票,但是会,因为它与 MySQL 没有直接关系,但你将其标记为这样。
  • 它与 MySQL 有关,因为我需要创建一个循环(或递归函数),以便将数据正确插入表中。可能你理解错了,或者我说的不是很清楚。
猜你喜欢
  • 2018-09-10
  • 2017-07-11
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-02
  • 1970-01-01
相关资源
最近更新 更多