Sql server 使用SQL Server,如何从While循环返回列表,我应该使用While循环吗?

Sql server 使用SQL Server,如何从While循环返回列表,我应该使用While循环吗?,sql-server,Sql Server,我有一个表A,其中有列Id和ParentId。给定一个Id,我想返回所有ParentId 也就是说,给定一个Id,我想返回所有条目'ParentId,然后我想检查记录的ParentId是否作为Id输入到表中,如果是这样,我想找到它的ParentId,等等 例如,如果我有一个简单的表格示例,如: Id | ParentID ---+--------- 1 0 2 1 3 2 4 3 5 4 6 5 7 6 我要打印Id=7的所有父项的查询如下所

我有一个表A,其中有列
Id
ParentId
。给定一个
Id
,我想返回所有
ParentId

也就是说,给定一个
Id
,我想返回所有条目'
ParentId
,然后我想检查记录的
ParentId
是否作为Id输入到表中,如果是这样,我想找到它的
ParentId
,等等

例如,如果我有一个简单的表格示例,如:

Id | ParentID
---+---------
1    0    
2    1
3    2
4    3
5    4 
6    5
7    6
我要打印
Id=7的所有父项的查询如下所示:

DECLARE @ParentId INT;

SET @ParentId = 7;

WHILE(@ParentId > 0)
BEGIN 
  SELECT @ParentId = ParentId
  FROM A
  WHERE Id = @ParentID

  PRINT @ParentId
END
tblParents.ParentID
1 --Children are 1,2,3
2 --Children are 4,5,6
3 --Children are 7,8,9

tblChildren.ChildID, tblChildren.ParentID
1,1 --Parent 1's children
2,1
3,1
4,2 --Parent 2's children
5,2
6,2
7,3 --Parent 3's children
8,3
9,3
此查询打印所有的
父ID
。但是,有没有办法返回ID?在这种情况下,若我从PHP调用这个查询,我希望得到parentID的列表,但我的查询实际上并没有返回任何内容

此外,我想知道while循环是否是正确的解决方案。递归查询会更快吗?如果是这样,关于如何将其转换为递归查询,有什么建议吗

*编辑

我需要从PHP访问ParentID列表。现在,我试图构建一个逗号分隔的ID列表,以便从查询返回,稍后我可以用PHP解析它。但是,下面的查询给了我一个错误:

具有返回值的RETURN语句不能在此上下文中使用

我应该如何返回列表?此外,在PHP中执行此语句时,如何获取返回值

SELECT  child.ParentID
FROM    A child
            INNER JOIN A parent
            ON child.Id = parent.ParentID
结果

0  
1  
2  
3  
4  
5  
6  
7  
返回字符串列表的步骤

DECLARE @List NVARCHAR(MAX)

SELECT  @List = COALESCE(@List + ',', '') + child.ParentID
FROM    A child
            INNER JOIN A parent
            ON child.Id = parent.ParentID

SELECT  @List
结果

0,1,2,3,4,5,6,7

while循环之后返回ID的方法是创建表变量以在进程中存储它们

declare @parents table
(
  LVL int primary key identity(1,1), -- [optional] level in hierarchy
  ParentID int
)
DECLARE @ParentId INT;
SET @ParentId = 7;
WHILE(@ParentId > 0)
BEGIN 
  SELECT @ParentId=ParentId
  FROM   A
  WHERE  Id=@ParentID

  -- PRINT @ParentId
  if (@ParentId > 0)
  insert into @parents (ParentID) values (@ParentId)
END

select * from @parents 
如果需要递归查询,请尝试在sql server中搜索
递归cte

可以创建一个
@parentList varchar(max)
变量,并以字符串
'6,5,4,3,2,1'
的形式返回结果,然后在客户端将其拆分,但这种格式在db中没有用处

DECLARE @ParentId INT, @ParentList varchar(max) = '';
-- @ParentList should be initialized with non-NULL value

SET @ParentId = 7;

WHILE(@ParentId > 0)
BEGIN 
  SELECT @ParentId = ParentId
  FROM A
  WHERE Id = @ParentID

  SET @ParentList = @ParentList + CAST(@ParentId as varchar(20)) + ','; 
END
select @ParentList;

只是一个建议,如果您可以创建和维护两个表(一个用于家长,一个用于孩子),那么您可以利用这两个数据集之间的关系。因此,RDBMS中的R。如果您有3位家长,每个家长有3个孩子,则可能如下所示:

DECLARE @ParentId INT;

SET @ParentId = 7;

WHILE(@ParentId > 0)
BEGIN 
  SELECT @ParentId = ParentId
  FROM A
  WHERE Id = @ParentID

  PRINT @ParentId
END
tblParents.ParentID
1 --Children are 1,2,3
2 --Children are 4,5,6
3 --Children are 7,8,9

tblChildren.ChildID, tblChildren.ParentID
1,1 --Parent 1's children
2,1
3,1
4,2 --Parent 2's children
5,2
6,2
7,3 --Parent 3's children
8,3
9,3
回到你原来的问题。在这种情况下,如果知道ChildID,可以使用ParentID将子表和父表连接在一起。然后,您只需知道ChildID即可获得父信息

其他评论回答了您的问题,但没有解决您的数据建模问题


希望有帮助

While循环和递归方法调用是等价的。它们在性能方面是等价的吗?While循环总是会从性能的角度受到影响。通常,递归cte不会遭受相同的性能损失。根据你的描述,我认为递归cte正是你所需要的。我不打算在这里详细回答这个问题,我建议你看看这个。但是tl;dr,使用递归实现它不会有什么帮助,尽管它也不会有什么坏处。你能解释一下为什么这会给出@ab11所寻找的解决方案吗?它不是一个解决方案。查询等于从一个
I add COALESCE函数中选择ParentID以返回结果作为一个ID列表。没有在循环中建立一个列表,然后在循环完成后返回列表的概念?@ab11,它是一个关系数据库,所以它与表一起工作。可以创建一个
@parentList varchar(max)
变量,并以字符串
'6,5,4,3,2,1'
的形式返回结果,然后在客户端将其拆分,但这种格式在db中没有用处。为什么不简单地返回一组值呢?我从php调用这个查询。我需要它返回一个ID列表,所以你的建议似乎正是我想要做的。但是我很难让它工作。你能看看我对我的问题所做的编辑吗?@ab11,什么是上下文?它是标量函数吗?如果它是一个简单的查询,而不是函数,请尝试
select@ParentList
int而不是
RETURN@ParentList
它是一个简单的函数。我有构建查询并调用数据库的php代码。我想从结果中提取parentID列表。