【问题标题】:How to split a numeric field into smaller segments in Sql Server如何在 Sql Server 中将数字字段拆分为更小的段
【发布时间】:2015-07-01 14:47:48
【问题描述】:

我在 SQL Server 中有一个包含两个字段的表。

Total      Group
35645      24
12400      55
30000      41

我想将每个组分成固定大小为 7000 的较小段,每组的其余部分放入最后一个段。因此,输出应如下所示。

Segment  Total     Group
1        7000       24
2        7000       24
3        7000       24
4        7000       24
5        7000       24
6        645        24
1        7000       55
2        5400       55
1        7000       41
2        7000       41
3        7000       41
4        7000       41
5        2000       41

【问题讨论】:

    标签: sql-server split group-by tile


    【解决方案1】:

    应该这样做:

    declare @t table (Total int,[Group] int)
    insert into @t(Total,[Group]) values
    (35645,24 ),
    (12400,55 ),
    (30000,41 )
    ;With Numbers as (
        select ROW_NUMBER() OVER (ORDER BY number)-1 n
        from master..spt_values
    )
    select
        n.n+1 as Segment,
        CASE WHEN (n.n+1)*7000 < t.Total THEN 7000
        ELSE t.Total - (n.n*7000) END as Total,
        t.[Group]
    from
        @t t inner join
        Numbers n on n.n*7000 < t.Total
    

    (如果您已经有一个 Numbers 表,则可以消除该部分。我使用 spt_values 只是因为我知道其中有很多行,因此 ROW_NUMBER() 表达式应该生成所有必要的数字)

    结果:

    Segment              Total                Group
    -------------------- -------------------- -----------
    1                    7000                 24
    2                    7000                 24
    3                    7000                 24
    4                    7000                 24
    5                    7000                 24
    6                    645                  24
    1                    7000                 55
    2                    5400                 55
    1                    7000                 41
    2                    7000                 41
    3                    7000                 41
    4                    7000                 41
    5                    2000                 41
    

    【讨论】:

    • 你比我快,我刚看完,看到了你的回答。好一个
    • 在此表上进行快速搜索 (master..spt_values) 显示了很多不建议使用此表的链接,因为它是一个遗留且未记录的表。因此,我并不是说您的答案是错误的,但也许创建自己的表来拆分值会更好,因为您永远不知道该表何时会被弃用。 (只需我的 2 美分)。 无论如何,我 +1 推荐了一些关于 SQL Server 的新内容
    • @Radu 我同意。使用具有 10 个值和几个交叉连接的 cte 将生成一个零读取的漂亮计数表。然而,对于像这个一样可靠的答案来说,这有点挑剔。
    • @SeanLange 不是说这不是一个可靠的答案,而是根本没有说。特别是CTE 之后的部分纯粹是优雅的。我只是想引起其他意见的注意。
    • @RaduGheorghiu - 但请注意,我小心不要使用该表中的 。我纯粹将它用作具有大量行的表。我会为此效果添加注释
    【解决方案2】:

    我使用 SQL CTE expressionSQL numbers table 函数准备了以下 SELECT 语句

    declare @divisor int = 7000
    ;with CTE as (
    select 
        Total, 
        [Group],
        @divisor divisor,
        (Total / @divisor) quotient,
        (Total % @divisor) reminder
    from t
    ), NT as (
        SELECT i FROM dbo.NumbersTable(1, (select max(quotient) from CTE) ,1)
    )
    select
        case when i = 0 then reminder else divisor end as Total,
        [Group]
    from (
    
        select * 
        from CTE, NT
        where quotient >= i
    
        union all
    
        select *, 0 as i
        from CTE
        where reminder >= 0
    
    ) t
    order by [Group], i desc
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-25
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多