在SQL Server中,如何使行的总和为1.0,直到总和为1.0

在SQL Server中,如何使行的总和为1.0,直到总和为1.0,sql,sql-server,aggregate-functions,Sql,Sql Server,Aggregate Functions,我被这个SQL Server查询卡住了;这是我的一套记录: Name Value ---- ---- abc 0.7 xyz 0.4 pqr 0.6 ijk 0.3 fgh 0.1 cde 1.0 uvw 0.8 我想要一个查询,它将给我一个值的总和,直到它达到1.0或更大 然后继续下一行,如 Names Value ----- ----- abc,xyz 1.1 pq

我被这个SQL Server查询卡住了;这是我的一套记录:

Name    Value
----    ----
abc      0.7
xyz      0.4
pqr      0.6
ijk      0.3
fgh      0.1
cde      1.0
uvw      0.8
我想要一个查询,它将给我一个值的总和,直到它达到1.0或更大 然后继续下一行,如

Names         Value
-----         -----
abc,xyz       1.1
pqr,ijk,fgh   1.0
cde           1.0
uvw           0.8
请帮我回答这个问题;我尝试使用分区和递归CTE,但到目前为止没有任何效果。

SQL表表示无序集。您的结果假设一个特定的排序,并且没有用于排序的列。下面假设存在这样一个列。它只是被称为
id

据我所知,这类问题需要递归CTE(或其他迭代处理)。这里有一种方法:

with t as (
      select t.*, row_number() over (order by id) as seqnum
      from mytable t
     ),
     cte as (
      select top (1) seqnum, convert(varchar(max), name) as name, convert(decimal(10, 1), value) as value,
             (case when value >= 1.0 then 1 else 0 end) as is_new
      from t
      order by seqnum
      union all
      select t.seqnum, 
             (case when cte.value >= 1 then t.name else concat(cte.name, ',', t.name) end),
             convert(decimal(10, 1), (case when cte.value > =1 then t.value else t.value + cte.value end)),
             (case when cte.value >= 1 then 1 else 0 end) as is_new
      from cte join
           t
           on t.seqnum = cte.seqnum + 1
     )
select name, value as sum_value
from (select cte.*, lead(name) over (order by seqnum) as nextname
      from cte
     ) cte
where nextname is null or nextname not like name + '%';

是一个dbfiddle。

您也可以使用从中看到的游标来求解


订单就是名字还是什么?是的,订单就是名字。我不知道你说的“订单就是名字”是什么意思。例如,如果您按名称ASC订购,则不会得到“abc,xyz”。@S_Sky。SQL表表示无序集。您的结果假定为有序。你们有这样一个列吗?我想按原始表的顺序检索结果集,我在示例中给出的是怎样的。非常感谢你们,你们给了我我想要的。谢谢你们,这真的很有帮助。
    DECLARE 
       @name VARCHAR(MAX), 
       @value FLOAT,
       @total FLOAT,
       @names VARCHAR(MAX);

    SET @total = 0.0;
    SET @names = '';

    DECLARE name_value CURSOR FOR 
    SELECT name, value FROM table_1;

    OPEN name_value;

    FETCH NEXT FROM name_value INTO @name, @value;

    WHILE @@FETCH_STATUS = 0
        BEGIN
            IF (@total >= 0.999)
            BEGIN
              INSERT INTO temp_table_1 VALUES(@names, @total);
              Set @total = 0.0;
              Set @names = '';
            END
            Set @total += @value;
            Set @names += @name  + ',';
            FETCH NEXT FROM name_value INTO  @name, @value
        END

    CLOSE name_value;
    INSERT INTO temp_table_1 VALUES(@names, @total); 
    DEALLOCATE name_value;
   GO
    SELECT * FROM temp_table_1
GO