===SQL中的数据 循环或递归查询的问题,求高人指点?谢谢!

junoveia 2014-09-28 04:11:47


如图:上图是数据库中的表,下图是我自己画的数据之间的关系。
问题:如何根据第一个红色张三的编号获得该会员及以下的所有的会员信息(按推荐关系)?获取到的数据中按级别进行累加(初级+1,中级+2,高级+3)。
1张三 初级+1
2李四 中级+2
3王五 高级+3
4赵六 中级+2
6李玉清 高级+3
7赵几凡 中级+2
结果:13
用C#如何实现这样的算法啊?上面展示的只是一小部份,用循环还是用递归啊,哪们大神可以帮我一下?我是新手,最好有具体步骤。谢谢!
...全文
347 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
j911 2014-09-30
  • 打赏
  • 举报
回复
引用 11 楼 junoveia 的回复:
[quote=引用 9 楼 u013264700 的回复:] 这个图递归遍历比较复杂,我的思路这样弄 1.查找xxx的推荐编号 2.查找xxx推荐的其他人,并且记录查找出的其他人的的推荐编号,返回1 继续查找 3.查找出的数据保存在map[xxx] = {xxx1,xxx2,xxx3},保存用户名或者其他需要显示的数据 4.最终结果,遍历map key 就是 推荐人,value 就是被推荐人
你的思路是可以,但是怎么样让程序跑起来?要有一个不断变化的编号才行啊,循环能实现吗? [/quote] 数据结构大概是这样: xxx介绍了xxx1;xxx1介绍了xxx4 xxx6;xxx4 介绍了xxx7,xxx8,xxx9;xxx5 介绍了xxx10,xxx11,xxx12, 这就是个树形结构了。 map[xxx] = {xxx1} 可以叫root map[xxx1] = {xxx4,xxx5} map[xxx4] = {xxx7,xxx8,xxx9} map[xxx5] = {xxx10,xxx11,xxx12} 最后大概得到这样一个字典,遍历,排序,啥的不都很方便么。 字典本身能遍历,字典内的列表也能遍历,至于你字典用什么作为key 列表里存什么,这个看你喜好,肯定不存数据库ID,不然取详细数据还要查询,一次性遍历出来一次性放入比较方便。
puler 2014-09-30
  • 打赏
  • 举报
回复
静静看一下,学习一下
junoveia 2014-09-30
  • 打赏
  • 举报
回复
引用 9 楼 u013264700 的回复:
这个图递归遍历比较复杂,我的思路这样弄 1.查找xxx的推荐编号 2.查找xxx推荐的其他人,并且记录查找出的其他人的的推荐编号,返回1 继续查找 3.查找出的数据保存在map[xxx] = {xxx1,xxx2,xxx3},保存用户名或者其他需要显示的数据 4.最终结果,遍历map key 就是 推荐人,value 就是被推荐人
你的思路是可以,但是怎么样让程序跑起来?要有一个不断变化的编号才行啊,循环能实现吗?
j911 2014-09-29
  • 打赏
  • 举报
回复
这个图递归遍历比较复杂,我的思路这样弄 1.查找xxx的推荐编号 2.查找xxx推荐的其他人,并且记录查找出的其他人的的推荐编号,返回1 继续查找 3.查找出的数据保存在map[xxx] = {xxx1,xxx2,xxx3},保存用户名或者其他需要显示的数据 4.最终结果,遍历map key 就是 推荐人,value 就是被推荐人
  • 打赏
  • 举报
回复
引用 4 楼 caozhy 的回复:
用递归可以,不过要用一个数据结构标记出已经遍历过的节点(图论中叫做找出图中的环路),这样就不会陷入无限递归了。
同意。 比较简单的做法是仅仅用一个“深度”参数(整数)作为参数就行了,一旦深度超过(比如说)20级,就不在深入了。
  • 打赏
  • 举报
回复
引用 6 楼 smthgdin 的回复:
还应该有1个字段去标示上一级节点吧。 不然你怎么知道推荐编号1的是张三而不是张娜。
做为一个“算法”它在可执行的方法参数中传递参数,而不是在输出的结果列表中增加字段。需要什么输出就只输出那些文字,这完全可以。
dianjixue1 2014-09-29
  • 打赏
  • 举报
回复
可以这样做,不采用递归。 1.建立表TUser是这样的 ID UName AssoNo Grade Sex Age -------------------- ----------------------------------------------- -------------------- ----------- ---- ----------- 1 张三 admin 1 男 22 2 李四 1 2 NULL NULL 3 王五 1 3 NULL NULL 4 赵六 2 2 NULL NULL 5 张娜 admin 1 NULL NULL 6 李玉清 1 3 NULL NULL 7 赵凡凡 4 2 NULL NULL 其中初级、中级、高级直接采用相对应的数字表示了,否则可以写一张关联表 在SQL中建立一个存储过程,下面示例把结果写在了输出参数里。也可以直接返回

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

/*
* 1.SYSTEM		: TUser
* 2.DB OWNER    : dbo
* 3.DESCRIPTION : 获取所有的关联级别
* 4.Author		: Dianjixue1
* 5.IN/OUTPUT	:
* ----------------------------------------------------------------------------
*    I/O         Type      PARA NAME              DESCRIPTION
* ----------  ---------- ---------------  ------------------------------------
*   [IN]         VARCHAR	@ID					查询ID
*   [OUT]        INT		@TotalGrade			与查询人员相关联的总级别数
* ----------------------------------------------------------------------------
*
* 6.HISTORY :
* ----------------------------------------------------------------------------
*/
CREATE PROCEDURE [dbo].[GetTotalGrade]
(
	@ID VARCHAR(20),								--查询的人员ID
	@TotalGrade INT OUTPUT                          --与查询人员相关联的总级别数,输出参数
)
AS
	SET NOCOUNT ON
	
	BEGIN 

		DECLARE @TEMPT TABLE(Temp_ID VARCHAR(20),TLEVEL INT)--将放入本ID及所有子级ID  
		 --插入本ID
		INSERT INTO @TEMPT(Temp_ID,TLEVEL) VALUES (@ID,1)   
		DECLARE @LEVEL INT --深度
		DECLARE @COUNT INT --受影响的行数
		SET @COUNT = 1
		SET @LEVEL = 1
		WHILE (@COUNT>0)
			BEGIN
			  INSERT INTO @TEMPT(Temp_ID, TLEVEL)
			  SELECT A.ID ,@LEVEL + 1
			  FROM TUser A,@TEMPT B 
			  WHERE A.AssoNo = B.Temp_ID      
				  AND TLEVEL = @LEVEL
			  SET @COUNT = @@ROWCOUNT
			  SET @LEVEL = @LEVEL + 1
			END
		 SELECT @TotalGrade = SUM(A.Grade) FROM TUser A,@TEMPT B
		 WHERE A.ID = B.Temp_ID
    END

在SQL中调用存储过程查看,例如查找与张三相关的

DECLARE @idd INT
EXEC GetTotalGrade 1,@idd OUTPUT           --1为张三的ID
SELECT @idd
在C#中调用就不写了
smthgdin_020 2014-09-28
  • 打赏
  • 举报
回复
还应该有1个字段去标示上一级节点吧。 不然你怎么知道推荐编号1的是张三而不是张娜。
  • 打赏
  • 举报
回复
引用 楼主 junoveia 的回复:
用循环还是用递归
可以先写出精炼的递归算法,然后有闲功夫的时候再变为迭代。
threenewbee 2014-09-28
  • 打赏
  • 举报
回复
用递归可以,不过要用一个数据结构标记出已经遍历过的节点(图论中叫做找出图中的环路),这样就不会陷入无限递归了。
gw6328 2014-09-28
  • 打赏
  • 举报
回复
节点类 组成树,用深度或者广度优先来遍历。即可。
-------_------- 2014-09-28
  • 打赏
  • 举报
回复
WITH CTE AS ( SELECT 姓名,推荐编号,级别 FROM 表 WHERE 姓名 = '张三' UNION ALL SELECT CTE.* FROM CTE INNER JOIN 表 ON 表.推荐编号 = CTE.姓名 ) SELECT DISTINCT * FROM CTE SQL2005以上

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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