<tfoot id='QfRgk'></tfoot>
  • <small id='QfRgk'></small><noframes id='QfRgk'>

    <legend id='QfRgk'><style id='QfRgk'><dir id='QfRgk'><q id='QfRgk'></q></dir></style></legend>

      <bdo id='QfRgk'></bdo><ul id='QfRgk'></ul>
  • <i id='QfRgk'><tr id='QfRgk'><dt id='QfRgk'><q id='QfRgk'><span id='QfRgk'><b id='QfRgk'><form id='QfRgk'><ins id='QfRgk'></ins><ul id='QfRgk'></ul><sub id='QfRgk'></sub></form><legend id='QfRgk'></legend><bdo id='QfRgk'><pre id='QfRgk'><center id='QfRgk'></center></pre></bdo></b><th id='QfRgk'></th></span></q></dt></tr></i><div id='QfRgk'><tfoot id='QfRgk'></tfoot><dl id='QfRgk'><fieldset id='QfRgk'></fieldset></dl></div>

        mysql 层次结构自加入,检索所有子类别

        mysql hierarchy self-join, retrieve all subcategories(mysql 层次结构自加入,检索所有子类别)

            <tbody id='ADeQA'></tbody>

              • <small id='ADeQA'></small><noframes id='ADeQA'>

              • <legend id='ADeQA'><style id='ADeQA'><dir id='ADeQA'><q id='ADeQA'></q></dir></style></legend>
                  <bdo id='ADeQA'></bdo><ul id='ADeQA'></ul>
                  <i id='ADeQA'><tr id='ADeQA'><dt id='ADeQA'><q id='ADeQA'><span id='ADeQA'><b id='ADeQA'><form id='ADeQA'><ins id='ADeQA'></ins><ul id='ADeQA'></ul><sub id='ADeQA'></sub></form><legend id='ADeQA'></legend><bdo id='ADeQA'><pre id='ADeQA'><center id='ADeQA'></center></pre></bdo></b><th id='ADeQA'></th></span></q></dt></tr></i><div id='ADeQA'><tfoot id='ADeQA'></tfoot><dl id='ADeQA'><fieldset id='ADeQA'></fieldset></dl></div>
                  <tfoot id='ADeQA'></tfoot>

                • 本文介绍了mysql 层次结构自加入,检索所有子类别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我有包含以下列的表 categories:

                  I have table categories that contains following columns:

                  category_id
                  category_name
                  parent_id
                  

                  我需要获取给定主类别的所有级别的所有子类别的列表,因此,例如,如果我给出某些 3 级类别的 ID,我将返回所有 4、5、6 级......类别的列表是那个 lvl 3 类别的孩子.

                  I need to get list of all subcategories on all levels for a given main category, so if for example I give id of some lvl 3 category I would get back list of all lvl 4, 5, 6... categories that are children of that one lvl 3 category.

                  不需要保留层次结构,只需一个简单的列表.

                  No hierarchy needs to be preserved, just a simple list.

                  我一开始想只用几个连接和子查询来做,但我认为之后类别会更深,所以这不是一条路.

                  I first thought about just doing it with several joins and subqueries but than I figured categories will bee much deeper afterwards so that's not a way to go.

                  由于我刚刚开始使用 SQL,我仍然不知道如何编写递归查询,所以这将是一个很好的帮助和学习材料.

                  Since I've just started SQL I still don't know how to write recursive queries so this would be a great help and learning material.

                  推荐答案

                  先阅读底部的请注意.好的,你回来了.

                  Read Please Note at bottom first. Ok good, you are back.

                  为类似递归的层次结构检索创建存储过程.

                  Creation of a Stored Procedure for recursive-like hierarchy retrieval.

                  请注意,您不希望按级别进行设置,但这很容易做到.

                  Note, you didn't want it by levels but that can easily be done.

                  create table category
                  (   category_id int not null auto_increment primary key,
                      category_name varchar(40) not null,
                      parent_id int null,  -- index on this column not a shabby idea
                      unique key (category_name)
                  );
                  
                  insert category(category_name,parent_id) values ('car',null),('food',null); -- 1,2
                  insert category(category_name,parent_id) values ('ford',1),('chevy',1),('fruit',2); -- 3,4,5
                  insert category(category_name,parent_id) values ('economy',3),('escort',6),('exhaust',7); -- 6,7,8
                  insert category(category_name,parent_id) values ('chassis',7),('loud',8),('banana',5); -- 9,10,11
                  -- ok granted I could have explicity inserted category_id to make it more obvious
                  

                  创建存储过程:

                  -- drop procedure showHierarchyBelow;
                  delimiter $$
                  create procedure showHierarchyBelow
                  (
                  catname varchar(40)
                  )
                  BEGIN
                      -- deleteMe parameter means i am anywhere in hierarchy of role
                      -- and i want me and all my offspring deleted (no orphaning of children or theirs)
                      declare bDoneYet boolean default false;
                      declare working_on int;
                      declare theCount int;
                      declare findFirst int;
                  
                      select ifnull(category_id,0) into findFirst from category where category_name=catname;
                  
                      CREATE TABLE xx_RecursishHelper_xx
                      (   -- it's recurshish, not recursive
                          category_id int not null,
                          processed int not null
                      );
                      if isnull(findFirst) then
                          set findFirst=0;
                      end if;
                      insert into xx_RecursishHelper_xx (category_id,processed) select findFirst,0;
                      if (findFirst=0) then
                          set bDoneYet=true;
                      else
                          set bDoneYet=false;
                      end if;
                  
                      while (!bDoneYet) do
                          -- I am not proud of this next line, but oh well
                          select count(*) into theCount from xx_RecursishHelper_xx where processed=0;
                  
                          if (theCount=0) then 
                              -- found em all
                              set bDoneYet=true;
                          else
                              -- one not processed yet, insert its children for processing
                              SELECT category_id INTO working_on FROM xx_RecursishHelper_xx where processed=0 limit 1;
                              insert into xx_RecursishHelper_xx (category_id,processed)
                              select category_id,0 from category
                              where parent_id=working_on;
                  
                              -- mark the one we "processed for children" as processed
                              update xx_RecursishHelper_xx set processed=1 where category_id=working_on;
                          end if;
                      end while;
                  
                      delete from xx_RecursishHelper_xx where category_id=findFirst;
                  
                      select x.category_id,c.category_name
                      from xx_RecursishHelper_xx x
                      join category c
                      on c.category_id=x.category_id;
                  
                      drop table xx_RecursishHelper_xx;
                  END
                  $$
                  

                  测试存储过程:

                  call showHierarchyBelow('food');
                  +-------------+---------------+
                  | category_id | category_name |
                  +-------------+---------------+
                  |           5 | fruit         |
                  |          11 | banana        |
                  +-------------+---------------+
                  
                  call showHierarchyBelow('car');
                  +-------------+---------------+
                  | category_id | category_name |
                  +-------------+---------------+
                  |           3 | ford          |
                  |           4 | chevy         |
                  |           6 | economy       |
                  |           7 | escort        |
                  |           8 | exhaust       |
                  |           9 | chassis       |
                  |          10 | loud          |
                  +-------------+---------------+
                  
                  call showHierarchyBelow('ford');
                  +-------------+---------------+
                  | category_id | category_name |
                  +-------------+---------------+
                  |           6 | economy       |
                  |           7 | escort        |
                  |           8 | exhaust       |
                  |           9 | chassis       |
                  |          10 | loud          |
                  +-------------+---------------+
                  
                  call showHierarchyBelow('xxx');
                  -- no rows
                  

                  请注意,我只是根据您的需要修改了我几个月前的答案.

                  Note I merely modified this Answer of mine from a few months ago for your needs.

                  以上仅用于说明目的.在现实世界中,我永远不会在存储过程中创建表.DDL 开销很大.相反,我会使用具有会话概念的预先存在的非临时表.并将其从已完成会话的行中清除.所以不要把上面的东西当作稻草人,等着你让它变得更好.询问这是否令人困惑.

                  The above is for illustrative purposes only. In a real world situation, I would never do create tables in a stored proc. The DDL overhead is significant. Instead, I would use pre-existing non temp tables with a session concept. And clean it out of rows for the session done. So do not take the above as any more than a straw man, waiting for you to make it more performant as such. Ask if that is confusing.

                  这篇关于mysql 层次结构自加入,检索所有子类别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Building a comma separated list?(建立一个逗号分隔的列表?)
                  Errors in SQL Server while importing CSV file despite varchar(MAX) being used for each column(尽管每列都使用了 varchar(MAX),但在导入 CSV 文件时 SQL Server 中出现错误)
                  How can I import an Excel file into SQL Server?(如何将 Excel 文件导入 SQL Server?)
                  Export table to file with column headers (column names) using the bcp utility and SQL Server 2008(使用 bcp 实用程序和 SQL Server 2008 将表导出到带有列标题(列名称)的文件)
                  Concat field value to string in SQL Server(将字段值连接到 SQL Server 中的字符串)
                  SQL Server Bulk insert of CSV file with inconsistent quotes(SQL Server 批量插入带有不一致引号的 CSV 文件)
                • <i id='KkB7Z'><tr id='KkB7Z'><dt id='KkB7Z'><q id='KkB7Z'><span id='KkB7Z'><b id='KkB7Z'><form id='KkB7Z'><ins id='KkB7Z'></ins><ul id='KkB7Z'></ul><sub id='KkB7Z'></sub></form><legend id='KkB7Z'></legend><bdo id='KkB7Z'><pre id='KkB7Z'><center id='KkB7Z'></center></pre></bdo></b><th id='KkB7Z'></th></span></q></dt></tr></i><div id='KkB7Z'><tfoot id='KkB7Z'></tfoot><dl id='KkB7Z'><fieldset id='KkB7Z'></fieldset></dl></div>
                    <tbody id='KkB7Z'></tbody>

                  <small id='KkB7Z'></small><noframes id='KkB7Z'>

                      <tfoot id='KkB7Z'></tfoot>
                        <bdo id='KkB7Z'></bdo><ul id='KkB7Z'></ul>
                          <legend id='KkB7Z'><style id='KkB7Z'><dir id='KkB7Z'><q id='KkB7Z'></q></dir></style></legend>