永发信息网

SQL语句:查询出所有有联系的数据(高手来)

答案:5  悬赏:30  手机版
解决时间 2021-04-22 16:18

有一张表,包含ID和Parent ID,也就是说,其中一条数据的ID可能会作为另一条数据的Parent ID出现。

现在我想查询出和一个指定ID有联系的所有数据,不管是父节点的兄弟节点,还是它的子节点,或它的子节点的子节点,兄弟节点的子节点,等等。

例如:

table:test

ID Parent ID

1 5

2 1

3 2

4 1

5 -

6 5

7 -

8 4

9 -

10 6

当指定的ID是1,2,3,4,5,6,8,10任意一个的时候,那么这几条数据都应该被查询出来。(因为需要查询出所有有联系的数据,不管是子节点还是父节点还是兄弟节点甚至是延伸出来的数据,都应该被查询出来)

当ID是9的时候就只有一条ID为9的数据。

这个查询能否使用一条SQL语句就实现了呢?这是一个函数来实现的,这个函数可以多次执行SQL以便完善SQL语句,但是最终还是需要仅仅一条SELECT语句能得到一个完整的结果集。

请大家帮帮忙,非常感谢。

(目前我的方法是使用迭代的方法,不断地增加SQL语句中的where子语句以便获取所有数据,但是这个方法有一个限制,SQL语句的长度是有限制的,所以希望大家能想想起他方法)

最佳答案

现在都些什么人,不仔细回答就不要乱拷贝,有什么意思。


你的问题1个SQL应该实现不了,不过这样就行了,也很简单,你可以多些数据测测,如果有其他更好的方法可以告诉我


---------------------建立 Temporarily 临时表----------------------------


DECLARE @Temporarily TABLE (Temporarilyid int, TemporarilyPId int)


---------------------申明临时变量a,b,存储你的第一个查询条件,这个固定----------------------------
DECLARE @a int
set @a=(SELECt ID1 as a FROM test WHERe ID1 = 1)
DECLARE @b int
set @b=(SELECt ParentID as b FROM test WHERe ID1 = 1)


---------------------将第一条结果插入临时表----------------------------
INSERT INTO @Temporarily VALUES (@a,@b)


---------------------循环执行,循环数为你记录的条数,这个不固定----------------------------
DECLARE @i int
SET @i = 1
WHILE @i <= 10
BEGIN


---------------------临时变量e,返回表的某条数据是否符合你的子父关联要求----------------------------
DECLARE @e int
set @e=(SELECt distinct Temporarilyid as e FROM @Temporarily WHERe Temporarilyid IN(SELECt ParentID FROM test WHERe ID1 = @i) or TemporarilyPId in(SELECt ID1 FROM test WHERe ID1 = @i))
---------------------符合,执行插入操作----------------------------


IF @e>0
BEGIN
set @a=(SELECt ID1 as c FROM test WHERe ID1 = @i)
set @b=(SELECt ParentID as d FROM test WHERe ID1 = @i)
INSERT INTO @Temporarily VALUES (@a,@b)
END


SET @i = @i + 1
END


---------------------显示结果集----------------------------
SELECt Temporarilyid AS a,TemporarilyPId AS b FROM @Temporarily



觉对可以满足你说的要求,多少条数据都可以,具体说一条sql语句执行,我还没想到可以的

全部回答
试试 视图,

出现这种情况 是数据库设计的不好。假如能修改数据库的话会给你带来很大的方便

增加一个字段 字段中就保存上层级关系 例如

1

1-1

1-1-1

1-1-1-1

1-1-2

1-2

1-3

无论你选中 哪个节点,要得到他的所有儿子 只需要 like 节点+'-%'即可得到,而改变此表结构工作量也不是很大,你只用在增加节点位置多修改这个字段的值即可。

如果不修改表结构 就只能用上述方法,递归或者循环了。虽然 递归循环可以得到相同结果但是效率并不理想

楼上那个方法是oracle的start with ... connect by ...,SQL中没有这个关键字

可以看看下面的资料,希望对你有用

SQL Sever 联机丛书: 访问和更改关系数据 展开层次结构 数据库经常存储层次信息。例如,下面的数据是全球一些地区的层次表示形式。这种表示形式并未清楚地显示出数据中隐含的结构。 Parent Child ---------------------------------- ---------------------------------- World Europe World North America Europe France France Paris North America United States North America Canada United States New York United States Washington New York New York City Washington Redmond 而下面的示例则更容易解释: World North America Canada United States Washington Redmond New York New York City Europe France Paris 下面的 Transact-SQL 过程将一个编码的层次展开到任意深度。尽管 Transact-SQL 支持递归,但是使用临时表作为堆栈来跟踪所有正在处理中的项目(已经开始但尚未结束),将更加有效。某个项目一旦处理完毕,将被从堆栈中删除。当发现新的项目时,这些项目将被添加到堆栈中。 CREATE PROCEDURE expand (@current char(20)) as SET NOCOUNT ON DECLARE @level int, @line char(20) CREATE TABLE #stack (item char(20), level int) INSERT INTO #stack VALUES (@current, 1) SELECt @level = 1 WHILE @level > 0 BEGIN IF EXISTS (SELECT * FROM #stack WHERe level = @level) BEGIN SELECt @current = item FROM #stack WHERe level = @level SELECt @line = space(@level - 1) + @current PRINT @line DELETE FROM #stack WHERe level = @level AND item = @current INSERT #stack SELECt child, @level + 1 FROM hierarchy WHERe parent = @current IF @@ROWCOUNT > 0 SELECT @level = @level + 1 END ELSE SELECT @level = @level - 1 END -- WHILE 输入参数 (@current) 表示层次中的开始位置。它还跟踪主循环中的当前项目。 使用的两个局部变量分别是 @level(用于跟踪层次结构中的当前级别)和 @line(是用于构造缩进行的工作区)。 SET NOCOUNT ON 语句避免输出中夹杂每个 SELECT 产生的 ROWCOUNT 消息。 使用层次中开始点的项目标识符来创建和整理临时表 #stack,而 @level 被设置为与之匹配。#stack 中的 level 列允许同一个项目出现在数据库的多个级别中。虽然这种情况不适用于该示例中的地理数据,但是它可以用于其它示例。 在下面的示例中,当 @level 大于 0 时,该过程执行以下步骤: 如果当前级别 (@level) 的堆栈中有任何项目,该过程将选择其中一个,并称之为 @current。 缩进项目 @level 空格,然后打印该项目。 从堆栈中删除该项目以免重复处理它,然后将其所有子项目添加到堆栈的下一级 (@level + 1) 中。这是唯一使用层次表 (#stack) 的地方。 如果使用传统的编程语言,就必须找到每个子项目并将其逐个添加到堆栈中。而使用 Transact-SQL,只用一个语句就能找到并添加所有的子项目,以免又使用一个嵌套循环。 如果有子项目 (IF @@ROWCOUNT > 0),则下降一级处理它们 (@level = @level + 1);否则,继续在当前级别上处理。 最后,如果在当前级别的堆栈中没有待处理的项目,则返回到上一级,看上一级是否有待处理的项目 (@level = @level - 1)。当再没有上一级时,则展开完毕。

比如ID是9的时候:

select * from table start with ID = 9 connect by prior Parent ID= ID;

我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
怎样练突破?
魔兽争霸的剧情动画下载地址
叶儿圆 花儿美 根儿胖 泥里藏 是什么?
逸香园中餐厅地址在什么地方,想过去办事
分词前连词的使用
qq农家打不开
怎么用边际收益递减规律解释我国为什么实行计
牧场我怎么开通不了?
好几个晚上都梦见僵尸,说明什么
查李白写钱塘江大潮的句子啊啊啊
怎样正确的关闭Mp4的硬件(就是有键头的那个,
爱情能经的起时间与距离的考验吗?
怎样说服他?
我报的是辽宁大学计算机信息管理怎么知道被录
通达铝制品黑白铁在什么地方啊,我要过去处理
推荐资讯
DNFM明天更新什么活动称号啊?是什么属性?
为什么绝数车辆的前窗都是倾斜的,能利用光学
包年3G网卡有漫游吗?
西游Q记中的宝宝怎么+点
交相辉映的意思是什么,北京哪些地方可以买到
心中有座坟类似句子,求心里有座坟,葬着未亡
帮忙做两道高中数学选择题,谢谢了!
姓周的艺人都有谁
5A05铝板的材料力学性能,密度,弹性模量,屈服
韩版花样男子和流星雨哪个好?我个人认为流星
武林外传,我想群沙漠巫师和刺客,应该在哪个
按照国家规定,考导游证是怎么样一个程序??
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?