码迷,mamicode.com
首页 > 其他好文 > 详细

递归查询

时间:2015-07-11 18:14:42      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:

推广渠道表有ParentID字段,代表上下层级关系。现要统计每个推广员,推广了多少人?

技术分享
 1 --创建表结构,插入测试数据
 2 USE DBA_Monitor
 3 GO
 4 CREATE TABLE [dbo].[TGYinfo](
 5     [TGYID] [int] IDENTITY(1,1) NOT NULL,
 6     [Name] [varchar](50) NULL,
 7     [ParentID] [int] NULL,
 8     [CreateTime] [datetime] NULL,
 9  CONSTRAINT [PK_tgyTbl] PRIMARY KEY CLUSTERED 
10 (
11     [TGYID] ASC
12 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
13 ) ON [PRIMARY]
14 GO
15 ALTER TABLE [dbo].[TGYinfo] ADD  CONSTRAINT [DF_TGYinfo_CreateTime]  DEFAULT (getdate()) FOR [CreateTime]
16 GO
17 SET IDENTITY_INSERT [dbo].[TGYinfo] ON
18 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (1, N推广1, 0, CAST(0x0000A4D100182B20 AS DateTime))
19 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (2, N推广2, 0, CAST(0x0000A4D100182B21 AS DateTime))
20 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (3, N推广1_1, 1, CAST(0x0000A4D100185C2E AS DateTime))
21 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (4, N推广1_2, 1, CAST(0x0000A4D100185C2F AS DateTime))
22 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (5, N推广1_3, 1, CAST(0x0000A4D100185C3D AS DateTime))
23 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (6, N推广1_1_1, 3, CAST(0x0000A4D10021A746 AS DateTime))
24 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (7, N推广1_1_2, 3, CAST(0x0000A4D100A1132A AS DateTime))
25 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (8, N推广2_1, 2, CAST(0x0000A4D100A13AE0 AS DateTime))
26 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (9, N推广2_2, 2, CAST(0x0000A4D100A1428E AS DateTime))
27 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (10, N推广2_1_1, 8, CAST(0x0000A4D100A15D3C AS DateTime))
28 INSERT [dbo].[TGYinfo] ([TGYID], [Name], [ParentID], [CreateTime]) VALUES (11, N推广2_1_2, 8, CAST(0x0000A4D100A161F9 AS DateTime))
29 SET IDENTITY_INSERT [dbo].[TGYinfo] OFF
View Code

原始数据如下图所示,需要统计每个节点有多少下层用户

技术分享
网上很多针对单一节点返回所有下层关系的代码,参考修改运行结果能正常返回。试想如果能将每次的单一节点一并返回出来,问题就基本解决了。或者说用一个字段标识,某N行对应是节点N返回的结果

 1 --单一节点返回所有下层关系的代码
 2 ;with cte as
 3 (select TGYID,Name,ParentID from TGYinfo
 4  WHERE TGYID=1--单一节点
 5 union all
 6 select a.TGYID,a.Name,a.ParentID
 7 from TGYinfo a
 8 inner join cte c
 9 on c.TGYID=a.ParentID
10 )
11 select * from cte

技术分享
增加OrderID字段,区分数据由哪个节点返回

 1 --生成OrderID字段
 2 ;with cte as
 3 (select TGYID,Name,ParentID,convert(bigint,1000+TGYID) as OrderID--每层用四位编码
 4 from TGYinfo
 5 union all
 6 select a.TGYID,a.Name,a.ParentID,convert(bigint,c.OrderID*10000)+convert(bigint,a.TGYID) OrderID
 7 from TGYinfo a
 8 inner join cte c
 9 on c.TGYID=a.ParentID
10 )
11 select * from cte
12 order by convert(varchar,OrderID)

技术分享
根据OrderID统计各节点的下层用户数

 1 --最终统计结果
 2 ;with cte as
 3 (select TGYID,Name,ParentID,convert(bigint,1000+TGYID) as OrderID--每层用四位编码
 4 from TGYinfo
 5 union all
 6 select a.TGYID,a.Name,a.ParentID,convert(bigint,c.OrderID*10000)+convert(bigint,a.TGYID) OrderID
 7 from TGYinfo a
 8 inner join cte c
 9 on c.TGYID=a.ParentID
10 )
11 select b.*,a.TGCount from(
12 select left(OrderID,4)%1000 TGYID,count(*) TGCount from cte
13 group by left(OrderID,4)
14 ) a
15 inner join TGYinfo b
16 on a.TGYID=b.TGYID
17 order by a.TGYID

技术分享

上面这个语句适合表中记录数<10000,如果有多的话,对应代码中的数值要扩大

递归查询

标签:

原文地址:http://www.cnblogs.com/Uest/p/4636174.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!