简体   繁体   English

如何编写一个MYSQL查询,它将返回嵌套在父项下的子项?

[英]How to write a MYSQL query that will return children nested under parents?

I don't know if what I'm asking is even possible, but here's my situation. 我不知道我问的是否可能,但这是我的情况。 I have a table structured somewhat like this: 我的表格有点像这样:

+--------------------------------------------------+
|   id   |   parent_id   |   name   |   category   | ....
+--------------------------------------------------+
|    0   |       -1      |   item0  |      1       |
|    1   |        0      |   item1  |      1       |
|    2   |        0      |   item2  |      1       |
|    3   |        2      |   item3  |      1       | 
|    4   |        2      |   item4  |      1       | 
|    5   |       -1      |   item5  |      1       | 
+--------------------------------------------------+

A parent_id of -1 will mean it is a "base" item with no parent. parent_id为-1表示它是没有父级的“基础”项。 Each item will have more columns of information. 每个项目都有更多的信息列。 I need to somehow output all items in a category nested like the following: 我需要以某种方式输出嵌套的所有项目,如下所示:

item0 => item1    
      => item2
            => item3
            => item4  
item5  

I don't know if that makes sense or not, but hopefully it does! 我不知道这是否有意义,但希望它确实如此!

The only way I can think of doing this is making a query to get all of the "base" items (querying for rows with parent_id = -1) then iterate through every resulting row, querying for rows that have their parent_id equal to the current row's id, then repeating the process going deeper and deeper until there aren't any more children for a base item. 我能想到这样做的唯一方法是进行查询以获取所有“基础”项(查询具有parent_id = -1的行)然后遍历每个结果行,查询其parent_id等于当前行的行行的id,然后重复该过程越来越深,直到基本项目没有更多的子项。

Is there a better way? 有没有更好的办法?

Thanks!! 谢谢!!

It is not possible in pure SQL. 在纯SQL中是不可能的。

SQL is intended to work with relational data not trees (hierarchical data). SQL旨在处理关系数据而不是树(分层数据)。

You can represent tree in an SQL schema, however you won't be a able to result in a tree as you intend to do. 您可以在SQL模式中表示树,但是您无法按照自己的意愿生成树。

The only way to do is to get an usable result by making as many join as level you're storing. 唯一的方法是通过将尽可能多的连接作为您存储的级别来获得可用的结果。

Your current schema may support multiple level, however, it will be very difficult to manage more than one or two level. 您当前的架构可能支持多个级别,但是,管理多个或两个级别将非常困难。

You may be interested in Nested Set Model or Managing hierarchical data in mysql 您可能对嵌套集模型管理mysql中的分层数据感兴趣

There are some implementation of the Nested Set like this one to work with Doctrine 2 有一些嵌套集的实现,就像这个与Doctrine 2一起使用

This is not possible in pure SQL and it is one of the aspects of the relational model that generates most criticism. 这在纯SQL中是不可能的,它是产生大多数批评的关系模型的一个方面。

I would recommend you to read the links on this post: SQL "tree-like" query - most parent group 我建议你阅读这篇文章的链接: SQL“树状”查询 - 大多数父组

And also, if your application relies too much on this, I would suggest you to take a look at some non-relational databases that can represent this kind of data way better, such as MongoDB ( www.mongodb.org ) 而且,如果您的应用程序过分依赖于此,我建议您查看一些可以更好地表示此类数据的非关系数据库,例如MongoDB(www.mongodb.org)

I hope i understood well your question(it's pretty late here and i've just come from a bar), if i didnt, just correct me and i'll rewrite my answer. 我希望我能很好地理解你的问题(这里已经很晚了,我只是来自酒吧),如果我没有,只要纠正我,我会改写我的答案。

From the scenario given, i guess there's another parent table, isn't there? 根据给出的情景,我猜有另一个父表,不是吗?

Lets imagine it's attributes are id and name. 让我们想象它的属性是id和name。 Children table is the given one by you (w/o unnecessary attributes). 子表是您给定的一个(没有不必要的属性)。

mysql> insert into parent(name) values ('petr'),('tomas'),('richard');


mysql> insert into children(name,parent_id) values('michal',1),('tomas',1),('michal');


mysql> select parent.id,parent.name,children.name from parent left join children on parent.id = children.parent_id;

+----+---------+--------+
| id | name    | name   |
+----+---------+--------+
|  1 | petr    | michal |
|  1 | petr    | tomas  |
|  2 | tomas   | NULL   |
|  3 | richard | michal |
+----+---------+--------+

In order to do this multiple time (parent got child who got child who got child etc..) You can accomplish that by using multiple joins. 为了多次这样做(父母得到孩子谁得到孩子等...)你可以通过使用多个连接来实现这一点。

mysql> select parent.id,parent.name as Parent,children.name as Child,children2.name as Child2 from parent left join children on parent.id = children.parent_id left join children2 on children.id = children2.parent_id;
+----+---------+--------+--------+
| id | Parent  | Child  | Child2 |
+----+---------+--------+--------+
|  1 | petr    | michal | NULL   |
|  1 | petr    | tomas  | dan    |
|  1 | petr    | tomas  | pavel  |
|  2 | tomas   | NULL   | NULL   |
|  3 | richard | michal | michal |
+----+---------+--------+--------+

If i either didnt answer what you asked or you need further explanation let me know ;] 如果我没有回答你的问题,或者你需要进一步解释,请告诉我;]

Regards, 问候,

Releis Releis

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM