首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用TSQL计算级联销售折扣方案?

如何使用TSQL计算级联销售折扣方案?
EN

Stack Overflow用户
提问于 2013-12-16 19:37:19
回答 1查看 1K关注 0票数 2

假设一个包含3 DiscountPrograms的表,其中有指定的计算顺序。

代码语言:javascript
运行
复制
create table program (programid varchar(5), calc_order tinyint)

go

insert tblprogram(programid, calc_order)
values(prog1, 1)

insert tblprogram(programid, calc_order)
values(prog2, 2)

insert tblprogram(programid, calc_order)
values(prog3, 3)

go

..。以及分配给程序的产品表。

代码语言:javascript
运行
复制
create table tblproduct(productid varchar(11), programid varchar(5))

go

insert tblproduct(productid, programid)
values(productabc, prog1)
insert tblproduct(productid, programid)
values(productdef, prog2)
insert tblproduct(productid, programid)
values(productxyz, prog3)

go

..。和按产品分列的销售表

代码语言:javascript
运行
复制
create table tblsales(productid varchar(11), salesamount numeric(18,2))

go 

insert tblsales(productid, salesamount)
values(productabc, 150)

insert tblsales(productid, salesamount)
values(productdef, 500)

insert tblsales(productid, salesamount)
values(productxyz, 650)

go

属于prog1的产品的销售将有1%的折扣:

.01*productabcSales

或者..。

.01*150 = 1.50

属于prog2的产品的销售折扣为prog1的1% (销售减去以前的折扣):

.01*(productdefSales-(.01*productabcSales))

或者..。

.01*(500-(.01*150) = 4.985 )

属于prog3的产品的销售将获得2%的折扣,与销售额减( prog2减去已支付的金额(prog1支付的金额)相比):

.02*(productxyzSales-(.01*(productdefSales-(.01*productabcSales))))

或者..。

.02*(650-(.01*(500-(.01*150)= 12.9003

我在想,在不创建一堆临时表的情况下,一定有一种简单的方法可以做到这一点吗?也许是CTE?而且,可以有任意数量的节目.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-16 23:04:33

这里有一个基于集合的传说,它只是试图避免这样一个事实:光标是解决这个问题的正确方法。(非常、非常、非常罕见的一次这种说法是正确的)

我向您的discount表中添加了一个tblprogram列--这似乎是正确的位置--但显然,我对您的用例没有真正的了解(因此您希望相应地调整我的代码)。

我使用ROW_NUMBER()来确保calc_order值从1开始,并且是连续的(以便代码以后工作)。如果您的order by表中有关联,over()中的calc_order应该删除任何随机行为。显然,这只是我的谨慎--你比我更了解你的数据--所以如果这段代码过于防御性,直接使用calc_order

代码语言:javascript
运行
复制
select 
    ROW_NUMBER() over (order by prg.calc_order, prg.programid) as calc_order, 
    s.productid, 
    p.programid, 
    prg.discount, --  this is the additional column to hold your values
    s.salesamount,
    convert(decimal(7,5),0) as rebate
into #results
from tblsales s
join tblproduct p on p.productid=s.productid 
join tblprogram prg on prg.programid=p.programid

declare @calc_order int=1

while @@ROWCOUNT>0 begin

    update r set
        rebate=(r.salesamount-isnull((
                select rebate
                from #results 
                where calc_order=@calc_order-1
                ),0))*discount,
        @calc_order+=1
    from #results r
    where r.calc_order=@calc_order

end

select * 
from #results

生产:-

代码语言:javascript
运行
复制
calc_order  productid   programid  discount  salesamount  rebate
1           productabc  prog1      0.01      150.00       1.50000
2           productdef  prog2      0.01      500.00       4.98500
3           productxyz  prog3      0.02      650.00       12.90030

而且,如果while循环是一个游标,那么为了避免不可避免地投票支持光标是正确的--如果select循环是一个游标,那么就不需要嵌入在update中的select了,因为到目前为止,您将不可避免地将回扣的总数保持在运行中--从而避免了服务器的工作。我也看不出递归cte是如何避免这种情况的。如果您想让我把游标代码扔到这里,在下面放一条消息,我会添加它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20619405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档