栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

MySQL:在一个Statement上连接许多表

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MySQL:在一个Statement上连接许多表

如何在MySql中使用递归查询从树节点获取所有后代?

对于MySql来说,这确实是一个问题,这是解决这个问题的关键,但是您仍然可以选择。

假设您拥有这样的样本数据,但不像样本那么多,但足以证明:

create table treeNode(id int, parent_id  int,  name varchar(10), type varchar(10),level int);insert into treeNode (id, parent_id, name, type, level) values ( 1,  0,  'C1    ', 'CATEGORY', 1),( 2,  1,  'C1.1  ', 'CATEGORY', 2),( 3,  2,  'C1.1.1', 'CATEGORY', 3),( 4,  1,  'C1.2  ', 'CATEGORY', 2),( 5,  4,  'C1.2.1', 'CATEGORY', 3),( 3,  8,  'G1.1.1',    'GROUP', 3),( 4,  9,  'G1.2  ',    'GROUP', 2),( 5,  4,  'G1.2.1',    'GROUP', 3),( 8,  9,  'G1.1  ',    'GROUP', 2),( 9,  0,  'G1    ',    'GROUP', 1);

首选: 等级码

类似于treeNode表中name列的示例数据。( 我不知道该怎么说英语,请就。的正确表达对我进行评论

level pre
。)

要获得

C1
或的所有后代,
G1
可能会像这样简单:

select * from treeNode where type = 'CATEGORY' and name like 'C1%' ;select * from treeNode where type = 'GROUP' and name like 'G1%' ;

我非常喜欢这种方法,甚至需要我们在treeNode保存到应用程序之前生成这些代码。当我们有大量记录时,它将比递归查询或过程更有效。我认为这是一种很好的非规范化方法。

使用这种方法,您想要 加入* 的语句 可以是: *

SELECt distinct p.* --if there is only one tree node for a product, distinct is not neededFROM product pJOIN product_type pt     ON pt.id= p.parent_id -- to get product type of a productJOIN linked_TreeNode LC     ON LC.product_id= p.id -- to get tree_nodes related to a productJOIN (select * from treeNode where type = 'CATEGORY' and name like 'C1%' ) C --may replace C1% to concat('$selected_cat_name','%')     ON LC.treeNode_id = C.idJOIN (select * from treeNode where type = 'GROUP' and name like 'G1%' ) G --may replace G1% to concat('$selected_group_name','%')     ON LC.treeNode_id = G.idWHERe pt.name = '$selected_type'  -- filter selected product type, assuming using product.name, if using product.parent_id, can save one join by pt like your original sql

亲爱的,不是吗?

第二选择:等级编号

如DDL中所示,将一个级别列附加到treeNode表。

级别编号比应用程序中的 级别代码 容易维护。

使用级别号来获取所有后代

C1
G1
需要一些技巧:

SELECT id, parent_id, name, type, @pv:=concat(@pv,',',id) as link_ids   FROM (select * from treeNode where type = 'CATEGORY' order by level) as t  JOIN (select @pv:='1')tmp WHERe find_in_set(parent_id,@pv)    OR find_in_set(id,@pv); -- get all descendants of `C1`SELECT id, parent_id, name, type, @pv:=concat(@pv,',',id) as link_ids   FROM (select * from treeNode where type = 'GROUP' order by level) as t  JOIN (select @pv:=',9,')tmp WHERe find_in_set(parent_id,@pv)    OR find_in_set(id,@pv) ;

这种方法比第一种慢,但比递归查询快。

该问题的完整sql省略了。只需要用上面的两个查询替换C和G的那两个子查询。

笔记:

除非按级别编号或级别代码订购,否则它们将无法工作。您可以测试在这个最后的查询

[SqlFiddle](http://sqlfiddle.com/#!2/8150e/12)

,通过改变
order by level
order by id
看到的差异。

另一个选择:嵌套集模型

请参考此博客,我尚未测试。但是我认为这类似于最后两个选择。

它需要在treenode表中添加一个左数字和一个右数字,以将它们之间的所有后代ID括起来。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/575019.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号