算法问题:按记录总值比例分组记录!请大家帮忙
一张TableA,里面有ID、Value两个字段,sum(value)为总值(TValue),另还有一张不同物品占总值(TValue)比例的的表TableB,m_id为物品id,m_value为占Tvalue的部分值,问题如下:如何将TableA的记录根据不同m_id占总值(TValue)的m_value,分组到不同的m_id中去??
我表述的可能不是很明白,简单的说就是将 一堆记录按照value值累加相同的原则分入不同的分组,举个例子
TableA 有 50 条 记录,每条记录的id不同,value 有可能不同 , 但 sum(value)=TValue=100
TableB 有如下三条记录
m_id m_value
A 50
B 30
C 20
即A、B、C的m_value值=TValue=100
要求将TableA中的50条记录,分三组分别给A、B、C,同时这些分组的记录的value相加等于A、B、C的m_value
希望我的表达各位能明白,求算法解决方案,非常感谢!
--------------------编程问答-------------------- 楼主给测试数据和测试结果 --------------------编程问答-------------------- 晕,我不能直接编辑帖子说
测试数据少一点吧,要求表A的10条数据分组到表B的不同m_value中去,允许一定误差,误差值可以设定
TableA 10条记录 总值为100 TableB还是一样三条记录
id value m_id m_value
1 25 A 50
2 15 B 30
3 10 C 20
4 3
5 1
6 5
7 14
8 16
9 5
10 6 --------------------编程问答-------------------- 楼主想要的结果是什么?
要求表A的10条数据分组到表B的不同m_value中去,允许一定误差,误差值可以设定
不懂这句话的意思? --------------------编程问答-------------------- 学习,这个比较难 --------------------编程问答--------------------
就是表A中不同记录的value相加=表B中m_value,
比如现在A表中id=1、2、3的value相加就刚好等于B表中m_id位A的m_value
这样A表剩下的id的value值相加再匹配到B表其他的m_id,一次类推
万一匹配不到,那就允许误差,
可以设定一个误差值,在这个误差值内也算匹配成功
(即 |A表中id=1、2、3的value相加 - m_id位A的m_value|< 误差值 ) --------------------编程问答-------------------- 好像就是背包算法,大家给给建议 --------------------编程问答--------------------
--------------------编程问答--------------------
--> 测试数据:[TableA]
if object_id('[TableA]') is not null drop table [TableA]
create table [TableA]([id] int,[value] int)
insert [TableA]
select 1,25 union all
select 2,15 union all
select 3,10 union all
select 4,3 union all
select 5,1 union all
select 6,5 union all
select 7,14 union all
select 8,16 union all
select 9,5 union all
select 10,6
select flag,sum(value)from (
select *,flag=(id-1)/(select count(1)/3 from [TableA]) from [TableA]
)t
group by flag
/*
flag
----------- -----------
0 50
1 9
2 35
3 6
(4 行受影响)
*/
drop table [TableA]
非常感谢一直在帮忙解决问题
但结果好像有点问题,我要的结果应该类似如下
m_id=A的TableA的id(1、2、3)
m_id=B的TableA的id(7、8)
m_id=C的TableA的id(4、5、6、9、10)
或者
m_id=A的TableA的id(1、2、6、9)
m_id=B的TableA的id(7、8)
m_id=C的TableA的id(3、4、5、10)
再或者……
应该有很多种组合,但只要有一种全部匹配上,就可以
--------------------编程问答-------------------- 你都不知道你想要什么结果?
不明白你想要什么结果??? --------------------编程问答--------------------
--------------------编程问答--------------------
--> 测试数据:[TableA]
if object_id('[TableA]') is not null drop table [TableA]
create table [TableA]([id] int,[value] int)
insert [TableA]
select 1,25 union all
select 2,15 union all
select 3,10 union all
select 4,3 union all
select 5,1 union all
select 6,5 union all
select 7,14 union all
select 8,16 union all
select 9,5 union all
select 10,7
select m_id=case when flag=0 then 'A' when flag=1 then 'B' when flag=2 then 'C' end,m_value=sum(value)from (
select *,flag=(Row_Number() over(order by newid())-1)%(select count(1)/3 from [TableA]) from [TableA]
)t
group by flag
/*
m_id m_value
---- -----------
A 33
B 28
C 40
(3 行受影响)
*/
drop table [TableA]
就是数据分组啊,A表的数据按照不同的规则,放到不同的组中去
组合应该有很多种,但我只要求一种就可以 --------------------编程问答-------------------- 应该不是一句的sql语句能完成,因为我的分组规则有很多,所以应该是一个过程
我想知道解决的思路 --------------------编程问答--------------------
靠
你那是什么分组规则啊?问你了N遍,你都不说,你自己搞吧!
--------------------编程问答-------------------- 首先对数据进行排序,根据累加所有的数据,如果<=100,那么就为所有的值
如果大于100,那么就从最大的开始取值
假定为40,35,30....
那么选取40,结果查询小于等于(100-40或者40 里面的最小值)的数据,进行下一次,小于误差了就跳出就行了.
补充:.NET技术 , ASP.NET