Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 在一个SQL查询中获取所有父行_Mysql_Sql_Hierarchical Data - Fatal编程技术网

Mysql 在一个SQL查询中获取所有父行

Mysql 在一个SQL查询中获取所有父行,mysql,sql,hierarchical-data,Mysql,Sql,Hierarchical Data,我有一个简单的MySQL表,它包含一个类别列表,级别由父id决定: id name parent_id --------------------------- 1 Home 0 2 About 1 3 Contact 1 4 Legal 2 5 Privacy 4 6 Products 1 7 Support 1 我正试图做一个面包屑的痕迹。因此,我有孩子的“id”,我想让所有可用的家长迭代

我有一个简单的MySQL表,它包含一个类别列表,级别由父id决定:

id  name    parent_id
---------------------------
1   Home        0
2   About       1
3   Contact     1
4   Legal       2
5   Privacy     4
6   Products    1
7   Support     1
我正试图做一个面包屑的痕迹。因此,我有孩子的“id”,我想让所有可用的家长迭代链,直到我们到达0家。可以有任意数量的行或子行进入无限深度

目前,我正在为每个父级使用SQL调用,这很混乱。SQL中有没有一种方法可以在一个查询中完成这一切

我可以帮你

您可以通过一个查询检索所有元素,将其存储在数组中,然后进行迭代,
正如前面所解释的,我认为,使用一个查询是不容易做到这一点的

我建议您看一看,它似乎适合您的需要。

改编自:


马克·拜尔斯的回答太棒了

可能有点晚了,但是如果您还想在id=parent\u id时防止无限循环,即当数据被破坏时,您可以这样扩展答案:

    SELECT T2.id, T2.name
    FROM (
        SELECT
            @r AS _id,
            @p := @r AS previous,
            (SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id,
            @l := @l + 1 AS lvl
        FROM
            (SELECT @r := 5, @p := 0, @l := 0) vars,
            table1 h
        WHERE @r <> 0 AND @r <> @p) T1
    JOIN table1 T2
    ON T1._id = T2.id
    ORDER BY T1.lvl DESC

除上述解决方案外:

post
-----
id
title
author

author
------
id
parent_id
name


[post]

id  | title | author |  
----------------------
1   | abc   | 3      |


[author]

| id    | parent_id | name  |   
|---------------------------|
| 1     | 0         | u1    |
| 2     | 1         | u2    |
| 3     | 2         | u3    |
| 4     | 0         | u4    |
包括家长在内的作者可以访问该帖子

我想检查一下作者是否有权访问这篇文章

解决方案:

提供文章作者的id并返回其所有作者和作者的父母

SELECT T2.id, T2.username 
FROM (
    SELECT @r AS _id, 
        (SELECT @r := parent_id FROM users WHERE id = _id) AS parent_id,
        @l := @l + 1
    FROM
        (SELECT @r := 2, @l := 0) vars, 
        users h     
    WHERE @r <> 0) T1 JOIN users T2 
ON T1._id = T2.id;

@r:=2=>为@r变量赋值

如果您使用slug而不是id,则只需运行子查询来查找子类别的id。 表-类别 |id | parentId | slug| |-------------| |1 | 0 | u1| |2 | 1 | u2| |3 | 2 | u3| |4 | 0 | u4|


我用前面的答案作为例子,使smth更具可读性

SELECT  @org_id as id,
    (SELECT name FROM test.organizations WHERE id = @org_id) as name,
    (SELECT @org_id := parent_id FROM test.organizations WHERE id = @org_id) AS parent_id
FROM (SELECT @org_id := 4) vars, test.organizations org
WHERE @org_id is not NULL
ORDER BY id;
执行的结果如下所示:

只是为了快点 要自己检查,您需要将问题中的值输入数据库测试表中


当我为自己的分层表制定解决方案时,我查看了WP多级类别模型。基于这里提供的优秀答案,我进行了此查询,以获取Wordpress数据库中的父类别。我不是这方面的专家,但这在我这方面起了作用,可能会对寻找这样答案的人有所帮助

  SELECT T2.term_id,T3.name,T3.slug
    FROM (
        SELECT
            @r AS _id,
            @p := @r AS previous,
            (SELECT @r := parent FROM wp_term_taxonomy WHERE term_id = _id AND taxonomy = 'category') AS parent_id,
            @l := @l + 1 AS lvl
        FROM
            (SELECT @r := 8, @p := 0, @l := 0) vars,
            wp_term_taxonomy h
        WHERE @r <> 0 AND @r <> @p) T1
    JOIN wp_term_taxonomy T2 ON T1._id = T2.term_id AND T2.taxonomy = 'category'
    LEFT JOIN wp_terms T3 ON T3.term_id = T2.term_id
    ORDER BY T1.lvl DESC

接受的答案具有递归检索子用户的所有父用户的最佳解决方案。我已经根据我的需要修改了这个

对于MySQL 5.5、5.6和5.7

SELECT @r AS user_id, 
   (SELECT @r := parent_id FROM users_table WHERE id = user_id) AS parent_id, 
   @l := @l + 1 AS level 

   FROM (SELECT @r := 9, @l := 0) val, users_table WHERE @r <> 0 
注:id=9。其中9是子用户的id


如何反向查询,即从父级获取所有子级??最好的答案。如果有人能解释这个神奇的查询中发生了什么,那就太好了……PS:只有当ID是整数数据类型时,这才有效。id是字符串的地方不起作用。@KurtZhong,魔法本身就足够了,让它发挥作用吧!:但是如果我没有错,它会找到一个级别的父级,并更新变量以找到下一个。变量的这种用法创建了类似于在表上迭代的东西。
SELECT  @org_id as id,
    (SELECT name FROM test.organizations WHERE id = @org_id) as name,
    (SELECT @org_id := parent_id FROM test.organizations WHERE id = @org_id) AS parent_id
FROM (SELECT @org_id := 4) vars, test.organizations org
WHERE @org_id is not NULL
ORDER BY id;
CREATE TABLE organizations(
id        int(11) NOT NULL AUTO_INCREMENT,
name      varchar(45) DEFAULT NULL,
parent_id int(11)     DEFAULT NULL,
PRIMARY KEY (id));

insert into organizations values(1, "home", null);
insert into organizations values(2, "about", 1);
insert into organizations values(3, "contact", 1);
insert into organizations values(4, "legal", 2);
insert into organizations values(5, "privacy", 4);
insert into organizations values(6, "products", 1);
insert into organizations values(7, "support", 1);
  SELECT T2.term_id,T3.name,T3.slug
    FROM (
        SELECT
            @r AS _id,
            @p := @r AS previous,
            (SELECT @r := parent FROM wp_term_taxonomy WHERE term_id = _id AND taxonomy = 'category') AS parent_id,
            @l := @l + 1 AS lvl
        FROM
            (SELECT @r := 8, @p := 0, @l := 0) vars,
            wp_term_taxonomy h
        WHERE @r <> 0 AND @r <> @p) T1
    JOIN wp_term_taxonomy T2 ON T1._id = T2.term_id AND T2.taxonomy = 'category'
    LEFT JOIN wp_terms T3 ON T3.term_id = T2.term_id
    ORDER BY T1.lvl DESC
SELECT @r AS user_id, 
   (SELECT @r := parent_id FROM users_table WHERE id = user_id) AS parent_id, 
   @l := @l + 1 AS level 

   FROM (SELECT @r := 9, @l := 0) val, users_table WHERE @r <> 0 
with recursive parent_users (id, parent_id, level) AS (
  SELECT id, parent_id, 1 level
  FROM users_table
  WHERE id = 9
  union all
  SELECT t.id, t.parent_id, level + 1
  FROM users_table t INNER JOIN parent_users pu
  ON t.id = pu.parent_id
)
SELECT * FROM parent_users;