求一个sql, 级联查询

whos2002110 2014-03-14 03:03:12
表(行业表)主要字段是这样的:
id code name parent_code;
parent_code关联表中另外一个数据的code字段
数据:
1,'A','农、林、牧、渔业',null;
2,'1',‘农业’,'A';
parent_code=null 表示是最高级别(无父级)
从业务上理解, id=1这个行业是 id=2(农业)的父级, id=2 可能又是其它行业的父级, 整张表父子层次比较深
农、林、牧、渔业->农业->谷物种植->豆类种植 ...

我要做这样一个查询: 给你任意一个行业id,查询该行业及其所有子行业
若id=1,则结果
农、林、牧、渔业 + (农业,林业,畜牧业,渔业) +(谷物种植,水果种植,中药材种植,...)+(....) +...

求帮助, 不知道sql能不能实现
...全文
251 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
LongRui888 2014-03-18
  • 打赏
  • 举报
回复
引用 16 楼 whos2002110 的回复:
[quote=引用 15 楼 yupeigu 的回复:] [quote=引用 12 楼 whos2002110 的回复:] [quote=引用 10 楼 yupeigu 的回复:] [quote=引用 9 楼 whos2002110 的回复:]

WITH temp AS(
 -- 定位点成员
 SELECT * FROM industry
 WHERE id = 7567
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM industry A, temp B
 WHERE A.parent_code = B.code
)
SELECT * FROM temp
我试着改成这个样子,跑不了
mysql应该是没有递归查询的。。。 [/quote] 我在sql server环境中试了确实可行, 我想请教下这个递归起始的temp 是什么? 还有递归的中止条件[/quote] 这个temp 是cte,在oracle,sql server都有这个,这个只需要写一次,就可以引用多次,起到简化sql的效果。 而在cte中可以实现递归,分成两部分,第一部分就是union all之前的部分,是递归的开始部分,就像i = 1,然后union all是递归部分,i = i+1但是i<=xxx 然后最后的select 就是用来查询这个递归语句的[/quote] 我想问temp第一次的结果集是什么,from industry A, temp B; 这里temp 不是做为一个表么? 第一次是不是就是union all之前的部分? 后来的temp是整个() 里面的结果? 不知道我理解的对不对,因为sql执行是先括号里面的吧[/quote] 对的,可以这么理解
whos2002110 2014-03-18
  • 打赏
  • 举报
回复
引用 15 楼 yupeigu 的回复:
[quote=引用 12 楼 whos2002110 的回复:] [quote=引用 10 楼 yupeigu 的回复:] [quote=引用 9 楼 whos2002110 的回复:]

WITH temp AS(
 -- 定位点成员
 SELECT * FROM industry
 WHERE id = 7567
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM industry A, temp B
 WHERE A.parent_code = B.code
)
SELECT * FROM temp
我试着改成这个样子,跑不了
mysql应该是没有递归查询的。。。 [/quote] 我在sql server环境中试了确实可行, 我想请教下这个递归起始的temp 是什么? 还有递归的中止条件[/quote] 这个temp 是cte,在oracle,sql server都有这个,这个只需要写一次,就可以引用多次,起到简化sql的效果。 而在cte中可以实现递归,分成两部分,第一部分就是union all之前的部分,是递归的开始部分,就像i = 1,然后union all是递归部分,i = i+1但是i<=xxx 然后最后的select 就是用来查询这个递归语句的[/quote] 我想问temp第一次的结果集是什么,from industry A, temp B; 这里temp 不是做为一个表么? 第一次是不是就是union all之前的部分? 后来的temp是整个() 里面的结果? 不知道我理解的对不对,因为sql执行是先括号里面的吧
LongRui888 2014-03-18
  • 打赏
  • 举报
回复
引用 12 楼 whos2002110 的回复:
[quote=引用 10 楼 yupeigu 的回复:] [quote=引用 9 楼 whos2002110 的回复:]

WITH temp AS(
 -- 定位点成员
 SELECT * FROM industry
 WHERE id = 7567
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM industry A, temp B
 WHERE A.parent_code = B.code
)
SELECT * FROM temp
我试着改成这个样子,跑不了
mysql应该是没有递归查询的。。。 [/quote] 我在sql server环境中试了确实可行, 我想请教下这个递归起始的temp 是什么? 还有递归的中止条件[/quote] 这个temp 是cte,在oracle,sql server都有这个,这个只需要写一次,就可以引用多次,起到简化sql的效果。 而在cte中可以实现递归,分成两部分,第一部分就是union all之前的部分,是递归的开始部分,就像i = 1,然后union all是递归部分,i = i+1但是i<=xxx 然后最后的select 就是用来查询这个递归语句的
whos2002110 2014-03-18
  • 打赏
  • 举报
回复
引用 11 楼 oyc1992 的回复:
[quote=引用 10 楼 yupeigu 的回复:] [quote=引用 9 楼 whos2002110 的回复:]

WITH temp AS(
 -- 定位点成员
 SELECT * FROM industry
 WHERE id = 7567
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM industry A, temp B
 WHERE A.parent_code = B.code
)
SELECT * FROM temp
我试着改成这个样子,跑不了
mysql应该是没有递归查询的。。。 [/quote] http://www.2cto.com/database/201209/152513.html http://blog.csdn.net/vastskyjoe/article/details/4301646 楼主看看吧.mysql一窍不通 [/quote] 嗯,mysql下我用了比较笨的解决办法, 因为总的层级数是定的,我就union了多次,就是把递归拆解最大次数
--小F-- 2014-03-18
  • 打赏
  • 举报
回复
引用 12 楼 whos2002110 的回复:
[quote=引用 10 楼 yupeigu 的回复:] [quote=引用 9 楼 whos2002110 的回复:]

WITH temp AS(
 -- 定位点成员
 SELECT * FROM industry
 WHERE id = 7567
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM industry A, temp B
 WHERE A.parent_code = B.code
)
SELECT * FROM temp
我试着改成这个样子,跑不了
mysql应该是没有递归查询的。。。 [/quote] 我在sql server环境中试了确实可行, 我想请教下这个递归起始的temp 是什么? 还有递归的中止条件[/quote] TEMP是CTE名 终止条件就是搜寻不到满足条件的记录啊。。 另外MYSQL是有递归的。自己去BAIDU一下吧。
whos2002110 2014-03-18
  • 打赏
  • 举报
回复
引用 10 楼 yupeigu 的回复:
[quote=引用 9 楼 whos2002110 的回复:]

WITH temp AS(
 -- 定位点成员
 SELECT * FROM industry
 WHERE id = 7567
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM industry A, temp B
 WHERE A.parent_code = B.code
)
SELECT * FROM temp
我试着改成这个样子,跑不了
mysql应该是没有递归查询的。。。 [/quote] 我在sql server环境中试了确实可行, 我想请教下这个递归起始的temp 是什么? 还有递归的中止条件
直面人生 2014-03-17
  • 打赏
  • 举报
回复
引用 10 楼 yupeigu 的回复:
[quote=引用 9 楼 whos2002110 的回复:]

WITH temp AS(
 -- 定位点成员
 SELECT * FROM industry
 WHERE id = 7567
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM industry A, temp B
 WHERE A.parent_code = B.code
)
SELECT * FROM temp
我试着改成这个样子,跑不了
mysql应该是没有递归查询的。。。 [/quote] http://www.2cto.com/database/201209/152513.html http://blog.csdn.net/vastskyjoe/article/details/4301646 楼主看看吧.mysql一窍不通
LongRui888 2014-03-17
  • 打赏
  • 举报
回复
引用 9 楼 whos2002110 的回复:

WITH temp AS(
 -- 定位点成员
 SELECT * FROM industry
 WHERE id = 7567
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM industry A, temp B
 WHERE A.parent_code = B.code
)
SELECT * FROM temp
我试着改成这个样子,跑不了
mysql应该是没有递归查询的。。。
whos2002110 2014-03-17
  • 打赏
  • 举报
回复

WITH temp AS(
 -- 定位点成员
 SELECT * FROM industry
 WHERE id = 7567
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM industry A, temp B
 WHERE A.parent_code = B.code
)
SELECT * FROM temp
我试着改成这个样子,跑不了
whos2002110 2014-03-17
  • 打赏
  • 举报
回复
引用 6 楼 yupeigu 的回复:
把上面版主的代码修改了一下,去掉了变量: 建表语句

-- 建立演示环境
CREATE TABLE Dept(
 id int PRIMARY KEY, 
 parent_id int,
 name nvarchar(20))
 
INSERT Dept
SELECT 0, 0, N'<全部>' UNION ALL
SELECT 1, 0, N'财务部' UNION ALL
SELECT 2, 0, N'行政部' UNION ALL
SELECT 3, 0, N'业务部' UNION ALL
SELECT 4, 0, N'业务部' UNION ALL
SELECT 5, 4, N'销售部' UNION ALL
SELECT 6, 4, N'MIS' UNION ALL
SELECT 7, 6, N'UI' UNION ALL
SELECT 8, 6, N'软件开发' UNION ALL
SELECT 9, 8, N'内部开发'
GO
查询:


;WITH
DEPTS AS(
 -- 定位点成员
 SELECT * FROM Dept
 WHERE name = N'MIS'
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM Dept A, DEPTS B
 WHERE A.parent_id = B.id
)
SELECT * FROM DEPTS

引用 4 楼 fredrickhu 的回复:
就你的这个而言 
定位点成员可以这样

;with f as
(
select * from tb where parent_code is null --表示最高级别
union all
select a.* from tb as a inner join f as b on a.parent_code =b.code
)

select * from f
引用 5 楼 oyc1992 的回复:
[quote=引用 4 楼 fredrickhu 的回复:]
就你的这个而言 
定位点成员可以这样

;with f as
(
select * from tb where parent_code is null --表示最高级别
union all
select a.* from tb as a inner join f as b on a.parent_code =b.code
)

select * from f
cte递归就可以搞定了 [/quote] 我擦,忘记说了我用的mysql数据库, 之前都是用sql server
LongRui888 2014-03-17
  • 打赏
  • 举报
回复
如果是2000,那就只能用存储过程来实现了
LongRui888 2014-03-17
  • 打赏
  • 举报
回复
把上面版主的代码修改了一下,去掉了变量: 建表语句

-- 建立演示环境
CREATE TABLE Dept(
 id int PRIMARY KEY, 
 parent_id int,
 name nvarchar(20))
 
INSERT Dept
SELECT 0, 0, N'<全部>' UNION ALL
SELECT 1, 0, N'财务部' UNION ALL
SELECT 2, 0, N'行政部' UNION ALL
SELECT 3, 0, N'业务部' UNION ALL
SELECT 4, 0, N'业务部' UNION ALL
SELECT 5, 4, N'销售部' UNION ALL
SELECT 6, 4, N'MIS' UNION ALL
SELECT 7, 6, N'UI' UNION ALL
SELECT 8, 6, N'软件开发' UNION ALL
SELECT 9, 8, N'内部开发'
GO
查询:


;WITH
DEPTS AS(
 -- 定位点成员
 SELECT * FROM Dept
 WHERE name = N'MIS'
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM Dept A, DEPTS B
 WHERE A.parent_id = B.id
)
SELECT * FROM DEPTS

直面人生 2014-03-17
  • 打赏
  • 举报
回复
引用 4 楼 fredrickhu 的回复:
就你的这个而言 
定位点成员可以这样

;with f as
(
select * from tb where parent_code is null --表示最高级别
union all
select a.* from tb as a inner join f as b on a.parent_code =b.code
)

select * from f
cte递归就可以搞定了
--小F-- 2014-03-14
  • 打赏
  • 举报
回复
就你的这个而言 
定位点成员可以这样

;with f as
(
select * from tb where parent_code is null --表示最高级别
union all
select a.* from tb as a inner join f as b on a.parent_code =b.code
)

select * from f
E次奥 2014-03-14
  • 打赏
  • 举报
回复
这是个树形结构!
whos2002110 2014-03-14
  • 打赏
  • 举报
回复
引用 1 楼 fredrickhu 的回复:
BOM结构 论坛N多 。

-- 建立演示环境
CREATE TABLE Dept(
 id int PRIMARY KEY, 
 parent_id int,
 name nvarchar(20))
INSERT Dept
SELECT 0, 0, N'<全部>' UNION ALL
SELECT 1, 0, N'财务部' UNION ALL
SELECT 2, 0, N'行政部' UNION ALL
SELECT 3, 0, N'业务部' UNION ALL
SELECT 4, 0, N'业务部' UNION ALL
SELECT 5, 4, N'销售部' UNION ALL
SELECT 6, 4, N'MIS' UNION ALL
SELECT 7, 6, N'UI' UNION ALL
SELECT 8, 6, N'软件开发' UNION ALL
SELECT 9, 8, N'内部开发'
GO

-- 查询指定部门下面的所有部门
DECLARE @Dept_name nvarchar(20)
SET @Dept_name = N'MIS'
;WITH
DEPTS AS(
 -- 定位点成员
 SELECT * FROM Dept
 WHERE name = @Dept_name
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM Dept A, DEPTS B
 WHERE A.parent_id = B.id
)
SELECT * FROM DEPTS
GO

-- 删除演示环境
DROP TABLE Dept
谢谢, 能不能用静态sql呢, 我做web应用的
--小F-- 2014-03-14
  • 打赏
  • 举报
回复
BOM结构 论坛N多 。

-- 建立演示环境
CREATE TABLE Dept(
 id int PRIMARY KEY, 
 parent_id int,
 name nvarchar(20))
INSERT Dept
SELECT 0, 0, N'<全部>' UNION ALL
SELECT 1, 0, N'财务部' UNION ALL
SELECT 2, 0, N'行政部' UNION ALL
SELECT 3, 0, N'业务部' UNION ALL
SELECT 4, 0, N'业务部' UNION ALL
SELECT 5, 4, N'销售部' UNION ALL
SELECT 6, 4, N'MIS' UNION ALL
SELECT 7, 6, N'UI' UNION ALL
SELECT 8, 6, N'软件开发' UNION ALL
SELECT 9, 8, N'内部开发'
GO

-- 查询指定部门下面的所有部门
DECLARE @Dept_name nvarchar(20)
SET @Dept_name = N'MIS'
;WITH
DEPTS AS(
 -- 定位点成员
 SELECT * FROM Dept
 WHERE name = @Dept_name
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM Dept A, DEPTS B
 WHERE A.parent_id = B.id
)
SELECT * FROM DEPTS
GO

-- 删除演示环境
DROP TABLE Dept

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧