【问题标题】:MySQL: Select row and all related rowsMySQL:选择行和所有相关行
【发布时间】:2017-04-26 02:33:45
【问题描述】:

我有一个categories 表设置,例如:

ID    CatName      CatParent
1     Websites     NULL
2     Recipes      NULL
3     Programming  1
4     Helpful      3
5     Useless      3
6     Desserts     2

如果我有一个类别 ID,我想查询数据库以选择类别和所有父母,按祖先的顺序。每个类别都有一个CatParent,这是它的父级,如果没有父级,则为NULL

因此,例如,如果我的类别 ID 为 4,我想要一个返回的查询:

array('4','3','1'); // Helpful > Programming > Websites

或者,如果我的类别 ID 为 6:

array('6','2'); // Desserts > Recipes

或类别 ID 为 1:

array('1');

我将如何构建这个查询?

【问题讨论】:

  • 是否有最大类别深度?如果没有,你不能只用一个查询来做到这一点。
  • @Quagaar 不,没有最大类别深度,除非它被定义为异常高的东西......比如说,20。
  • 你试过循环吗? (sql,不是 php)
  • 您希望数据库中有多少个类别?

标签: php mysql


【解决方案1】:

您可以使用left join 来获取父类别,但这只有在有限制的情况下才有意义。对于无限的类别深度,我会在 PHP 中进行。不过,这里有一个示例查询:

select c1.id, c2.id, c3.id
from categories c1 
left join categories c2 on c2.id = c1.catparent
left join categories c3 on c3.id = c2.catparent
where c1.id = 4

如果类别 4 只有一个父级,则最后一个 ID (c3.id) 将为 NULL。您必须在代码中考虑到这一点。

【讨论】:

  • 感谢您发布此内容,但我无法让此内容返回任何结果。
  • 连接的表名中有错字(类别而不是类别)。但除此之外,查询还有效。
【解决方案2】:

为此,您可以创建一个过程。如果使用 phpmyadmin,您可以转到您的数据库,到 SQL 并插入以下内容:

DELIMITER //
CREATE PROCEDURE get_parents(IN cid int)
BEGIN
    DECLARE child_id int DEFAULT 0;
    DECLARE prev_id int DEFAULT cid;
    DECLARE loopran int DEFAULT 0; 

    SELECT CatParent into child_id 
    FROM categories WHERE ID=cid ;

    create TEMPORARY  table IF NOT EXISTS temp_table as (select * from categories where 1=0);
    truncate table temp_table;

    WHILE child_id <> 0 OR loopran <> 1 DO
        SET loopran = 1;

        insert into temp_table select * from categories WHERE ID=prev_id;
        SET prev_id = child_id;
        SET child_id=0;
        SELECT CatParent into child_id
        FROM categories WHERE ID=prev_id;
    END WHILE;

    select * from temp_table;
END //

该过程创建一个临时表来存储数据。变量loopran,只是为了确保即使该类别没有孩子,也会返回父母作为结果。

接下来,检索结果:

$id = 5;

$result = "
CALL get_parents($id)
"; // Call the procedure just like as if it were a php function

$query = mysqli_query($conn, $result) or die(mysqli_error($conn));

$x = 0;

while ($row = mysqli_fetch_array($query)) {
    if ($x > 0) echo ", ";
    echo $row['ID'] . " | " . $row['CatParent'];
    $x++;
}

$id = 4 返回:4 | 3, 3 | 1

$id = 6 返回:6 | 2

$id = 1 返回:1 |

$id = 9 不返回任何内容(当然,如果该行不存在。)

有一个大问题。也就是说,如果你最终进入一个循环,最终指向循环中的前一个 id,它将导致无限循环。要解决这个问题,您必须退出 while 循环,条件是它尝试添加已经添加的内容。但我认为这永远不会自然发生。 (当然取决于您使用它的目的,以及 ParentID 的设置方式)

来源和信用:@Meherzad - https://stackoverflow.com/a/16514403/2506641

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-29
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多