TSQL:按最大大小的数据包对文件进行分组的查询

TSQL:按最大大小的数据包对文件进行分组的查询,sql,sql-server,tsql,group-by,packet,Sql,Sql Server,Tsql,Group By,Packet,我面临的问题在第一种方法中可能不是很难,但它并不像可能的那么容易。 我有一个文件列表,它们的大小以MB为单位,可以从DB表中找到一个列表 例如: SELECT file_name, file_size FROM myfiles 结果: file_name | file_size ---------------------- file 1 | 14 file 2 | 5 file 3 | 20 file 4 | 6 我想实现一个SQL查询,该查询按数据包对文件进

我面临的问题在第一种方法中可能不是很难,但它并不像可能的那么容易。 我有一个文件列表,它们的大小以MB为单位,可以从DB表中找到一个列表

例如:

SELECT file_name, file_size
FROM myfiles
结果:

file_name | file_size    
----------------------
file 1    | 14
file 2    | 5
file 3    | 20
file 4    | 6
我想实现一个SQL查询,该查询按数据包对文件进行分组,以发送到API。 文件应按最大20 Mb的数据包重新分组。 最好的解决方案是在第三列中返回“发送索引”。 大概是这样的:

file_name | file_size | packet_index   
-------------------------------------
file 1    | 14        | 1 
file 2    | 5         | 1
file 3    | 20        | 2
file 4    | 6         | 3
第一次发送将包含文件1和2、第二个文件3和最后一个文件4。
如何在SQL中确定此信息?

不幸的是,此类问题需要递归CTE。您正在按顺序分配组,因此:

with tt as (
      select t.*, row_number() over (order by file_name) as seqnum
      from myfiles t
     ),
     cte as (
      select file_name, file_size, file_size as total, seqnum, 1 as grp
      from tt
      where tt.seqnum = 1
      union all
      select tt.filename, tt.filesize,
             (case when tt.filesize + cte.total > 20
                   then tt.filesize
                   else tt.filesize + cte.total 
              end),
             tt.seqnum,
             (case when tt.filesize + cte.total > 20
                   then cte.grp + 1
                   else cte.grp
              end)
      from cte join
           tt
           on tt.seqnum = cte.seqnum + 1
    )
select *
from cte;
他是一把小提琴


如果您有超过100行,则添加
选项(MAXRECURSION 0)

如果文件大小超过20 MB怎么办?是的,我忘了提到文件大小不能超过20 MB。非常感谢。仅供参考,此查询可能会引发类似“语句已终止。在语句完成之前,最大递归100已用尽”的错误。您应该在结束时配置“OPTION(maxrecursion 0)”以修复此问题,但这可能很危险,并可能导致无限循环。请小心。Re Gordon,它似乎不适用于这样的示例:我认为“当tt.filesize+cte.filesize>20时的情况”有一个问题,tt.filesize应该是当前数据包中所有上一个文件大小的总和,而不仅仅是上一个文件大小的文件大小。@NicoFC34。固定的。