表结构如下: tb1
ID OrderID Weight AutoID TotalWeight GroupID
3339 12800389 0.023800 1 0.023800
3339 12800272 0.045000 2 0.068800
3339 12800267 0.133000 3 0.201800
3339 12800254 0.750000 4 0.951800
3339 12800344 0.365000 5 1.316800
3339 12800315 0.047000 6 1.363800
3339 12800298 0.137000 7 1.500800
3339 12794841 0.765000 8 2.265800
3339 12794837 0.765000 9 3.030800
3339 12786045 0.865600 10 3.896400
3339 12786042 0.865600 11 4.762000
3339 12800679 0.033200 12 4.795200
3339 12800677 0.035100 13 4.830300
3339 12800633 0.057700 14 4.888000
3339 12800602 0.027000 15 4.915000
……
说明:AutoID 为自动生成
GroupID 为分组编号
现在 sum(Weight) 以1.5为倍数修改GroupID列
select GroupID,Sum(Weight) as GroupWeight from tb1 group by GroupID
使得这里面的 GroupWeight<=1.5 成立
我写了如下SQL来实现,在数据少的情况下是正确的,数据一多就出现问题了
SELECT *, ( SELECT SUM(Weight)
FROM tb1 t2
WHERE [t2].[AutoID] <= [t1].[AutoID]
AND [t2].[ID] = [t1].[ID]
) AS totalweight,
Cast(( ( SELECT SUM(Weight)
FROM tb1 t2
WHERE [t2].[AutoID] <= [t1].[AutoID]
AND [t2].[id] = [t1].[id]
) / 1.5 as int ) AS diffid
FROM tb1 t1
因为数据量一多,除完取整的话存在一定的误差,使得上面的GroupWeight>1.5
------解决方案--------------------
你的意思我是看明白了,但暂时没有想到集合解决的思路,只能临时用游标解决了,看看你的数据量大不大,不大,速度能够接受的话,你可以试试。
你的方法里面用累计求和除以1.5,这个方法本身有问题,与精度是没有关系的。
就是说下一个分组的值会分摊到上个分组中,这样你除出来可能没有超过1.5,但是实际已经超过了,
里面 AutoID =9,Weight= 0.765 ;AutoID =10,Weight= 0.8656 就是我上面说的情况,被你分组到一个组里面去了。
- SQL code
IF OBJECT_ID('tb1') IS NOT NULL DROP TABLE tb1GOCREATE TABLE tb1(ID int, OrderID varchar(10), Weight numeric(18, 6), AutoID int, TotalWeight numeric(18,6), GroupID int);GOINSERT INTO tb1(ID, OrderID, Weight, AutoID, TotalWeight)SELECT 3339, '12800389', 0.0238, 1, 0.0238 UNION ALLSELECT 3339, '12800272', 0.045, 2, 0.0688 UNION ALLSELECT 3339, '12800267', 0.133, 3, 0.2018 UNION ALLSELECT 3339, '12800254', 0.75, 4, 0.9518 UNION ALLSELECT 3339, '12800344', 0.365, 5, 1.3168 UNION ALLSELECT 3339, '12800315', 0.047, 6, 1.3638 UNION ALLSELECT 3339, '12800298', 0.137, 7, 1.5008 UNION ALLSELECT 3339, '12794841', 0.765, 8, 2.2658 UNION ALLSELECT 3339, '12794837', 0.765, 9, 3.0308 UNION ALLSELECT 3339, '12786045', 0.8656, 10, 3.8964 UNION ALLSELECT 3339, '12786042', 0.8656, 11, 4.762 UNION ALLSELECT 3339, '12800679', 0.0332, 12, 4.7952 UNION ALLSELECT 3339, '12800677', 0.0351, 13, 4.8303 UNION ALLSELECT 3339, '12800633', 0.0577, 14, 4.888 UNION ALLSELECT 3339, '12800602', 0.027, 15, 4.915;--*****************************************************--利用游标解决declare @aID int, @wei numeric(18,6);declare @GroupID int;declare @sumWeight numeric(18,6);declare @tmpT table(AutoID int, GroupID int);set @sumWeight = 0;set @GroupID = 0;declare C CURSOR fast_forward for select AutoID, [Weight] from tb1 order by AutoID;open Cfetch Next From C into @aID, @wei;while @@FETCH_STATUS = 0begin set @sumWeight = @sumWeight + @wei; if @sumWeight > 1.5 begin set @GroupID = @GroupID + 1; insert into @tmpT(AutoID, GroupID) Values(@aID, @GroupID); set @sumWeight = @wei; end else begin insert into @tmpT(AutoID, GroupID) Values(@aID, @GroupID); end fetch Next From C into @aID, @wei;endClose C;Deallocate C;--更新原表的GroupID数据update aset a.GroupID = b.GroupIDfrom tb1 a join @tmpT b on a.AutoID = b.AutoID;select * from Tb1; /*ID OrderID Weight AutoID TotalWeight GroupID----------- ---------- ---------- ----------- ------------ -----------3339 12800389 0.023800 1 0.023800 03339 12800272 0.045000 2 0.068800 03339 12800267 0.133000 3 0.201800 03339 12800254 0.750000 4 0.951800 03339 12800344 0.365000 5 1.316800 03339 12800315 0.047000 6 1.363800 03339 12800298 0.137000 7 1.500800 13339 12794841 0.765000 8 2.265800 13339 12794837 0.765000 9 3.030800 23339 12786045 0.865600 10 3.896400 33339 12786042 0.865600 11 4.762000 43339 12800679 0.033200 12 4.795200 43339 12800677 0.035100 13 4.830300 43339 12800633 0.057700 14 4.888000 43339 12800602 0.027000 15 4.915000 4*/