我有一张表,其中包含一个人员列表和一个持续时间值,我需要将表中每个人的总持续时间相加,并显示每个人的记录数。不使用游标的SQL条件分组
PersonTable
id int
name nvarchar(max)
duration decimal(18,2)
SELECT name, sum(duration) as TotalDuration, count(*) as NumRecords
FROM PersonTable
GROUP BY name
不幸的是,我还需要确保没有人被放置在持续时间超过3小时的组中。如果某个人的记录总数大于3小时,那么我需要为该人生成2个组,或者根据需要为总数保留3个以下的记录。基本表中没有单个记录包含持续时间> 3,所以一组有效的组总是可能的。
为了清楚测试数据:
id, person, duration
1, John Smith, 2hrs
2, John Smith, 1hrs
3, John Smith, 1hrs
4, John Smith, 2hrs
1, Jane Doe, 1hrs
1, Jane Doe, 1hrs
1, Jane Doe, 2hrs
8, Jack Foo, 1hrs
输出:(序列号来识别同一个人的不同的组)
name, Total Duration, Num Records, Sequence Number
John Smith, 3hrs, 2, 1
John Smith, 3hrs, 2, 2
Jane Doe, 2hrs, 2, 1
Jane Doe, 2hrs, 1, 2
Jack Foo, 1hrs, 1, 1
这issustrates的基本问题。在实践中有更多的字段可以分组,并且我还需要枚举基本记录的ID,因为这些记录将在稍后的阶段中使用。
我目前的解决方案是只使用游标遍历排序后的表,并在累计总小时数超过3时将新组输出到临时表。temorpary表还包含一列逗号分隔的每行id值的基表有助于分组。
但是我想知道是否有更好的(没有游标)解决这类问题。
也可以将聚合连接回基表,所以我有一张每个记录的表,再加上一个序列号,允许我将人和序列号分组以重现上面的表格?这将是一个更好的解决方案,比生成逗号分隔的ID列表,用于在过程的后期阶段找到原始记录。
该表是否具有将用于排序和分组的“主键”或其他列? –
是的,一个简单的自动增量ID列 – Trent