在SQL中计算族范围的基于集合的方法?

在SQL中计算族范围的基于集合的方法?,sql,tsql,Sql,Tsql,我有一个表,其中包含父项和每个父项的0个或更多子项,并带有一个标志,指示哪些记录是父项。给定族的所有成员都具有相同的父id,并且父id在给定族中始终是最低的。此外,每个子级都有一个与其关联的值。(具体来说,这是一个电子邮件和附件数据库,其中每个家长都是一封电子邮件,孩子是附件。) 我需要计算两个字段: 范围={族中最低的id}-{族中最高的id}[为所有成员填充] 值列表={每个子级的值的分隔列表,按id顺序}[仅适用于父级] 因此,鉴于此: Id | Parent| HasChildren|

我有一个表,其中包含父项和每个父项的0个或更多子项,并带有一个标志,指示哪些记录是父项。给定族的所有成员都具有相同的父id,并且父id在给定族中始终是最低的。此外,每个子级都有一个与其关联的值。(具体来说,这是一个电子邮件和附件数据库,其中每个家长都是一封电子邮件,孩子是附件。)

我需要计算两个字段:
范围={族中最低的id}-{族中最高的id}[为所有成员填充]
值列表={每个子级的值的分隔列表,按id顺序}[仅适用于父级]

因此,鉴于此:

Id | Parent| HasChildren| Value | Range | Value-list
----------------------------------------|-----------
 1 |    1  |     1      |       |       | 
 2 |    1  |     0      |  a    |       |  
 3 |    1  |     0      |  b    |       |  
 4 |    4  |     1      |       |       | 
 5 |    4  |     0      |  c    |       |  
 6 |    6  |     0      |       |       |  
最后,我想说:

Id | Parent| HasChildren| Value | Range | Value-list
----------------------------------------|-----------
 1 |    1  |     1      |       |  1-3  |  a;b
 2 |    1  |     0      |  a    |  1-3  |  
 3 |    1  |     0      |  b    |  1-3  |  
 4 |    4  |     1      |       |  4-5  |  c
 5 |    4  |     0      |  c    |  4-5  |  
 6 |    6  |     0      |       |  6-6  |  
我怎样才能有效地做到这一点?理想情况下,我希望只使用基于集合的逻辑,而不使用游标,甚至不使用存储过程。临时桌子可以

我在T-SQL中工作,如果这有什么不同的话,尽管我很想看到平台无关的答案。

下面的内容应该可以帮你完成,但是正如@Allan提到的,你可能需要修改你的数据库结构

使用CTE: 注意:我的查询使用
table1
作为表名

     with cte as(
     select parent
    ,ValueList= stuff(( select ';' +isnull(t2.Value, '') 
                   from table1 t2
                   where t1.parent=t2.parent
                   order by t2.value
                   FOR XML PATH(''), TYPE
                         ).value('.', 'NVARCHAR(MAX)'), 1, 2, '')

from table1 t1
group by parent
),

cte2 as (select parent
         , min(id) as firstID
         , max(id) as LastID 
         from table1 
         group by parent)

select *
,(select FirstID from cte2 t2 where t2.parent=t1.parent)+'-'+(select LastID from cte2 t2 where t2.parent=t1.parent) as [Range]
,(select ValueList from cte t2 where t1.parent=t2.parent and t1.[haschildren]='1') as [Value -List]
from table1 t1

我认为你在这里混淆了一些概念,我非常不确定你实际上必须从什么数据开始;以及通过“基于集合的逻辑”(关系数据库通常总是在数据集合上工作,除非您使用游标之类的东西)来计算什么以及如何计算。您是否正在尝试将某些现有数据重新整理为显示的数据?或者尝试在现有数据中插入新数据?如果Parent1得到一个新孩子会发生什么?它会得到Id 7,从而弄乱你的“范围”?等等……1)我编辑了(希望)更清楚地显示了我要计算的字段。2)是的,我所说的“基于集合”是指关系语句,而不是游标,或存储过程中的逻辑,即声明式而不是命令式3)我不能更改设计,它来自客户端;)谢谢,非常有帮助。我要补充的唯一一件事是,对于像我这样的SQL新手来说,我不知道如何将信息返回到我的原始表b/c中,我不知道您可以从联接进行更新。所以我在你的基础上做了一个。但我不知道这是不是最好的方法。它将上一个查询转换为另一个cte,然后使用该cte更新表。