1

我的问题有点类似于

按 T​​-SQL 中的每 N 条记录分组

但是我想按最高美元金额分组

所以我有 20 条记录,总共amount50,000,我需要将它们分成组,以便每个组的最大数量为 10,000。

我尝试使用一个运行值,给记录一个排名,然后将这些值相加 <= 当前排名,然后使用 将它们分成子组Floor((RunningValue - amount) / 10000),但在某些情况下它会超过 10,000 个最大值

样本数据,可以看到这里SubGroup 1 超过10,000

SubGroupNo  RowNo   amount  RunningValue
0           1       790.5   790.5
0           2       790.5   1581
0           3       790.5   2371.5
0           4       790.5   3162
0           5       744     3906
0           6       744     4650
0           7       1348.5  5998.5
0           8       1348.5  7347
0           9       1348.5  8695.5
1           10      1348.5  10044
1           11      1302    11346
1           12      1302    12648
1           13      1302    13950
1           14      1302    15252
1           15      1255.5  16507.5
1           16      1209    17716.5
1           17      1116    18832.5
1           18      1116    19948.5
2           19      1302    21250.5
2           20      1302    22552.5
2           21      1302    23854.5
2           22      1255.5  25110
2           23      1255.5  26365.5
2           24      976.5   27342
4

1 回答 1

2

这可能不是最好的方法,但它确实有效。它假定您RowNo的 ' 是连续的。如果没有,我会添加ROW_NUMBER()这个解决方案。

基于迭代的方法

SQL小提琴

DECLARE @runningTotal decimal(7,2), @sgn tinyint, @cursor int, @count int
SET @runningTotal = '0.00'
SET @sgn = 0
SET @cursor = 1
SELECT @count = COUNT(*) FROM tbl

WHILE @cursor <= @count
BEGIN
    SELECT @runningTotal = @runningTotal + amount FROM tbl WHERE RowNo = @cursor
    IF @runningTotal > 10000
        BEGIN
            SELECT @runningTotal = amount FROM dbo.tbl WHERE RowNo = @cursor
            SET @sgn = @sgn + 1
        END
    UPDATE tbl SET SubGroupNo = @sgn WHERE RowNo = @cursor
    SET @cursor = @cursor + 1
END

编辑 1:基于光标的方法

SET NOCOUNT ON;

DECLARE @SubGroupNo tinyint, @RowNo smallint, 
    @amount decimal(8,2), @RunningTotal decimal(7,2)

SET @SubGroupNo = 0
SET @RunningTotal = '0.00'

DECLARE row_cursor CURSOR FOR
    SELECT RowNo, amount FROM dbo.tbl

OPEN row_cursor

FETCH NEXT FROM row_cursor
INTO @RowNo, @amount

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @RunningTotal = @RunningTotal + @amount

    IF @RunningTotal > 10000
        BEGIN
            SET @RunningTotal = @amount
            SET @SubGroupNo = @SubGroupNo + 1
        END
    PRINT @RowNo 
    PRINT @RunningTotal
    PRINT @SubGroupNo

    UPDATE dbo.tbl SET SubGroupNo = @SubGroupNo WHERE RowNo = @RowNo

    FETCH NEXT FROM row_cursor
    INTO @RowNo, @amount
END

CLOSE row_cursor
DEALLOCATE row_cursor

结果

| 子组号 | 罗诺 | 数量 | 运行价值 |
----------------------------------------------
| 0 | 1 | 790.5 | 790.5 |
| 0 | 2 | 790.5 | 1581 |
| 0 | 3 | 790.5 | 2371.5 |
| 0 | 4 | 790.5 | 3162 |
| 0 | 5 | 第744章 3906 |
| 0 | 6 | 第744章 4650 |
| 0 | 7 | 1348.5 | 5998.5 |
| 0 | 8 | 1348.5 | 7347 |
| 0 | 9 | 1348.5 | 8695.5 |
| 1 | 10 | 1348.5 | 10044 |
| 1 | 11 | 第1302章 11346 |
| 1 | 12 | 第1302章 12648 |
| 1 | 13 | 第1302章 13950 |
| 1 | 14 | 第1302章 15252 |
| 1 | 15 | 1255.5 | 16507.5 |
| 1 | 16 | 第1209章 17716.5 |
| 2 | 17 | 1116 | 18832.5 |
| 2 | 18 | 1116 | 19948.5 |
| 2 | 19 | 第1302章 21250.5 |
| 2 | 20 | 第1302章 22552.5 |
| 2 | 21 | 第1302章 23854.5 |
| 2 | 22 | 1255.5 | 25110 |
| 2 | 23 | 1255.5 | 26365.5 |
| 2 | 24 | 976.5 | 27342 |

架构

CREATE TABLE tbl (
  SubGroupNo tinyint,
  RowNo tinyint PRIMARY KEY,
  amount decimal(6,2),
  RunningValue decimal(7,2))

INSERT INTO tbl (RowNo, amount, RunningValue)
VALUES
(1, '790.5', '790.5'),
(2, '790.5', '1581'),
(3, '790.5', '2371.5'),
(4, '790.5', '3162'),
(5, '744', '3906'),
(6, '744', '4650'),
(7, '1348.5', '5998.5'),
(8, '1348.5', '7347'),
(9, '1348.5', '8695.5'),
(10, '1348.5', '10044'),
(11, '1302', '11346'),
(12, '1302', '12648'),
(13, '1302', '13950'),
(14, '1302', '15252'),
(15, '1255.5', '16507.5'),
(16, '1209', '17716.5'),
(17, '1116', '18832.5'),
(18, '1116', '19948.5'),
(19, '1302', '21250.5'),
(20, '1302', '22552.5'),
(21, '1302', '23854.5'),
(22, '1255.5', '25110'),
(23, '1255.5', '26365.5'),
(24, '976.5', '27342')
于 2012-08-14T19:10:29.907 回答