【问题标题】:t-sql loop through all rows and sum amount from column until value is reachedt-sql 循环遍历所有行并从列中求和,直到达到值
【发布时间】:2020-06-01 23:52:36
【问题描述】:

我有一个包含以下测试数据的表格:

我现在想用 12 个座位来填满一家餐厅。

这应该会导致:

基本上,我需要从上到下循环遍历所有行并添加 AmountPersons 直到我填满了餐厅。

在这个例子中:

(前几行:AmountPersons)3+1+2+4 = 10

UserId 52 无法添加,因为他们为 3 人保留,这将导致 13 个被占用的位置,只有 12 个可用。

在下一行它注意到 1 的预订。这可以添加到我们已经找到的前 10 个。

NewTotal 现在是 11。

无法添加用户 ID 79 和 82,因为我们会再次超出容量。

UserId 95 为 1 保留,可以添加这个,现在我们已经填满了所有位置。

这是我从我使用的光标得到的结果,但我现在卡住了。请帮忙。

当下一个值高于 12 时,我在光标中的 while 循环基本上会停止。但这是不正确的。

【问题讨论】:

  • 请用您正在使用的数据库标记您的问题:mysql、oracle、postgresql...?
  • @GMB:标题不是说t-sql
  • @Dieter 。 . .标题不是标签。
  • 也许我有点头脑简单,但我会在处理每一行时填充一个临时表,跳过会导致总和 > 12 的行,并在总和时终止循环临时表中的行等于 12。然后我有一个引用(临时表),用于更新或删除源表中的行(例如,将“坐下”列更新为 TRUE)。我发现简单的方法可以更好地执行,并且更易于维护。
  • 以及如何确定行的顺序?你不应该先收集所有有 1s 的用户,然后是 2s 等,直到达到限制?不清楚的任务...

标签: sql-server tsql


【解决方案1】:

因为要跳过行,所以需要递归 CTE。但这很棘手——因为你可能没有一个遵循你的规则的组加起来正好是 12。

所以:

with tn as (
         select t.*, row_number() over (order by userid) as seqnum
         from t
        ),
       cte as (
        select userId, name, amountPersons as total, 1 as is_included, seqnum
        from tn 
        where seqnum = 1
        union all
        select tn.userId, tn.name, 
               (case when tn.amountPersons + cte.total <= 12
                     then tn.amountPersons + cte.total
                     else cte.total
                end),
               (case when tn.amountPersons + cte.total <= 12
                     then 1
                     else 0
                end) as is_included,
               tn.seqnum
        from cte join
             tn
             on tn.seqnum = cte.seqnum + 1
        where cte.total < 12
    )
select cte.*
from cte
where is_included = 1;

Here 是一个 dbfiddle。

请注意,如果将“I”更改为更大的值,则不包括在内,占用座位数为 11,而不是 12。

【讨论】:

  • order by userid 为什么要使用idordering?
  • @JohnyL 。 . .我不明白评论。此答案中没有 order by id 并且 dbfiddle 似乎可以工作。
  • @GordonLinoff 不确定这是否可行,但我有一个后续问题。如何在with tn as () 的查询中添加 ORDER BY 子句?我有这个名为 Count_Invited 的第五列,每次他们被邀请时都会增加。当我可以订购第一个 select 语句时,它会自动返回最少受邀的人。 ORDER BY Count_Invited ASC 返回错误ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP、OFFSET 或 FOR XML。
  • @GordonLinoff 没关系,我只需要更新row_number() over... 中的 ORDER BY 子句并使用 Count_Invited 而不是 userid。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多