向大家讨教一个算法(MS SQL2000)

jg3003 2007-10-18 07:24:46
最近接到一个案子, 是要做一个奖励系统

活动产品有两个 A 和B

Case1 A 卖3个 + B 卖2 个 --------奖励 20块
Case2 A 卖6个 + B 卖4 个 --------奖励 50块
Case3 A 卖10个 + B 卖5 个 --------奖励 100块


比如某一个店卖这两个产品, 需要算出来这家店最大奖励的金额是多少.

不知道有没有人做过类似的问题, 有没有什么好的算法.


...全文
167 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lwhlau 2007-10-19
  • 打赏
  • 举报
回复
数学没学好啊
fcuandy 2007-10-19
  • 打赏
  • 举报
回复
如于我所说的量, 我举的例子中因为只有一个 Require,所以就很衡量标准就简单的描述成了一个avg
而要是有多个条件组合, 那么就需要有其它的一个算法来得出这个一个avg (这个avg 是设置这个条件组合中量的确定的一个主要依具)

比如
A 物品 每卖一件 可以获纯利 15
B 物品 每卖一件 可以获纯利 25

他的基本规则也是这样来的.
获纯利多少,则可给奖励多少.
比如获纯利 60,可奖10

那么他设置条件就可能是
A B C
1 2 10

那么这里这一条规则的平均 你就不能用 10/(1+2) 这样来算

我们除了做数据, 对业务的了解也是必要的, 这样会提供更好的业务上建议以获得开发上更优的设计.
fcuandy 2007-10-19
  • 打赏
  • 举报
回复
fcuandy

你的这个方法只是一个目标的算法.
我需要的是A和B两个产品同时达到才可以. 可能就不太适用了!


理解层次不同, 话就比较难说.

我当然知道你 A和B两个产品同时到达才可以.

我上面示例的 Require 本身就指代了你的几个要求条件, 如果我不把 Require用int来表示,直接用一个 require statement(一个require的条件表达式) 来表述, 可能你就理解了, 但用条件表达式的话,我又无法直在SQL语句里体现, 所以直接用了个int.

还是那句话 理解层次不同,意境不同 话就比较难说.
jg3003 2007-10-19
  • 打赏
  • 举报
回复
不好意思, 我没有说清除, 这个是可以累加的!
比如如果是A:14, B:10 的话,
他的奖励应该是:
Case1 A 卖3个 + B 卖2 个 --------奖励 20块
Case3 A 卖10个 + B 卖5 个 --------奖励 100块

总计应该可以拿120块

加个group by 就行了.

select id ,
sum(case when a = 3 and b = 2 then 20 else 0 end) +
sum(case when a = 10 and b = 5 then 100 else 0 end)
from tb
group by id


我觉得你的这个算法上面还是有些问题的.
如果你是这样做case的话,应该是无法得到结果的.

还以 比如如果是A:14, B:10 为例
我没有办法分成你说写的case那样. 即便可以, 也需要对A和b的量进行递减.

jg3003 2007-10-19
  • 打赏
  • 举报
回复
fcuandy

你的这个方法只是一个目标的算法.
我需要的是A和B两个产品同时达到才可以. 可能就不太适用了!
dawugui 2007-10-19
  • 打赏
  • 举报
回复
不好意思, 我没有说清除, 这个是可以累加的!
比如如果是A:14, B:10 的话,
他的奖励应该是:
Case1 A 卖3个 + B 卖2 个 --------奖励 20块
Case3 A 卖10个 + B 卖5 个 --------奖励 100块

总计应该可以拿120块

加个group by 就行了.

select id ,
sum(case when a = 3 and b = 2 then 20 else 0 end) +
sum(case when a = 10 and b = 5 then 100 else 0 end)
from tb
group by id
fcuandy 2007-10-18
  • 打赏
  • 举报
回复
Require Charge
2 15
3 28
5 37
9 58

ReachRequire RequierID(Charge)
6 = 5(37) = 2+3(15+28)
7 = 2+5(15+37) = 2+2+2(15+15+15)
8 = 5+3(37+28) = 2+2+3(15+15+28) = 2+5(15+37)
9 = 9(58) = 2*4=(15*4) =3+3+2=(28+2+15) = 5+3(37+28) = 2+5(15+37)
12 对应的组合就更多了

随着 Require规则的增多,和 店面卖出量的增加,
使用哪种算法, 他应该满组某几条规则的组合而得到最大的SUM(charge)
无疑就是穷举了.

当然,这也要看设置 Require 规则的人对量的把握了.
比如
Require Charge avg
1 10 10
2 19 9.5
3 28 9.33
4 41 10.25

这样的量设置是不尽人意的,因为随着购买量的增加,现实中,需要的是更多的奖历,
当卖掉一个时可得10元,卖两个才19, 那我宁原都按第一个规则计算


Require Charge avg
1 10 10
2 21 10.5
3 33 11
4 45 11.25
这样的数据设置才是科学的.
如果对这个Require要求和Charge的数据设置很合理,那么可以采用简单的算法

就是找 商店 的 ReachRequire 符合的可得最大Charge的规则 设为CurRequire.
然后如果 ReachRequire - CurRequire 的值还能再符合其它的某条规则,
那么再在其中选最大的这个值所符合的规则, 这样一直进行下去,直到剩余值不满足
任何一条规则,那么将得到最大的Charge之和

declare @ReachCharge int,@TotalCharge INT
SELECT @ReachCharge=100,@TotalCharge=0
DECLARE @curRequire INT,@curCharge INT
while Exists(SELECT 1 FROM tb WHERE @ReachCharge>=Require)
BEGIN
SELECT @curRequire=Require,@curCharge=Charge FROM tb WHERE Require<=@ReachCharge ORDER BY Charge DESC
SELECT @totalCharge=@totalCharge + @curChage,@ReachCharge=@ReachCharge-@CurChage
--如果需要记录得出的组合,那么可以插个临时表或表变量记录
END

SELECT @totalCharge

随手敲的,难免有手误
中国风 2007-10-18
  • 打赏
  • 举报
回复
--生成一个奖励表
create TABLE #t(RequireA INT,RequireB INT,Charge INT)
INSERT #t SELECT 3,2,20
UNION ALL SELECT 6,4,50
UNION ALL SELECT 10,5,100
go
--销售表
create TABLE #T1(店名 nvarchar(5),产品 nvarchar(2),数量 INT)
INSERT #T1 SELECT '店1','A',6
UNION ALL SELECT '店1','B',3
UNION ALL SELECT '店2','A',8
UNION ALL SELECT '店2','B',6
go


select
店名,
sum(case when 产品='A' then 数量 else 0 end) as A数量,
sum(case when 产品='B' then 数量 else 0 end) as B数量
into #T2
from
#T1 t
group by
店名



select
店名,MAX(Charge) AS Charge
from
#T2 a,#t b
where
exists(select 1 from #t where Charge=B.Charge AND RequireA<=A数量 and RequireB<=B数量)
GROUP BY
店名
go
DROP TABLE #T,#T1,#T2
店名 Charge
----- -----------
店1 20
店2 50

(所影响的行数为 2 行)

fcuandy 2007-10-18
  • 打赏
  • 举报
回复
这个..
很早以前就讨论过了,理论上"最多奖历"需要穷举来实现.
没有什么好的算法.
jg3003 2007-10-18
  • 打赏
  • 举报
回复
不好意思, 我没有说清除, 这个是可以累加的!
比如如果是A:14, B:10 的话,
他的奖励应该是:
Case1 A 卖3个 + B 卖2 个 --------奖励 20块
Case3 A 卖10个 + B 卖5 个 --------奖励 100块

总计应该可以拿120块
fcuandy 2007-10-18
  • 打赏
  • 举报
回复
DECLARE @t TABLE (RequireA INT,RequireB INT,Charge INT)
INSERT @t SELECT 3,2,20
UNION ALL SELECT 6,4,50
UNION ALL SELECT 10,5,100

--设当前店家A的销售量为curA,B的销售量为curB
DECLARE @curA INT,@curB INT
SELECT @curA=7,@curB=5
SELECT TOP 1 * FROM @t WHERE RequireA<=@curA AND RequireB<=@curB ORDER BY Charge DESC

/*
RequireA RequireB Charge
----------- ----------- -----------
6 4 50
*/

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧