求“先进先出法”计算库存商品余额价值的SQL语句

NongCunGongLu 2014-01-22 06:11:43

MS-SQL数据库,表Tb的结构和内容如下

RecId InOrOut spId Dj Sl
------------------------------------------
1 1 999 590 120
2 -1 999 (800) (110)
3 1 999 580 80
4 -1 999 (800) (50)
5 1 999 570 100
6 1 999 560 50
7 -1 999 (800) (30)

上述记录是按RecId顺序发生的
其中InOrOut为1时,表明商品入库;InOrOut为-1时,表明商品出库
Dj和Sl分别是当时入库或出库时的单价、数量
spId是不同商品的ID,为了描述直观,表中只列出一种商品的情况

显然,在第7条记录(销售出库30件)完成时,spId为999的商品剩余160件,这160件商品的价值,按先进先出法,应为90800元,即:
第6条记录的(50*560=28000) + 第5条记录的(100*570=57000) + 第3条记录的(10*580=5800),合计为90800元

求计算表Tb中现余商品的价值的SQL语句,多谢(要考虑多种商品spId的情况)。
顺祝论坛朋友们,各位光临本贴的老师们,马年顺利!
...全文
518 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
NongCunGongLu 2014-01-24
  • 打赏
  • 举报
回复
引用 12 楼 tcmakebest 的回复:
写的SQL有人能看懂并得到好评我就很高兴了,补分就不必了,谢谢你的诚意,呵!加油
本想学着你的方法,再解决一个类似的问题,但是我失败了. 对sql了解得太少,一直不入门.. 劳驾去拿分吧, 如果能顺便帮我解决一下问题, 就太感谢了. 请点击:http://bbs.csdn.net/topics/390699977
tcmakebest 2014-01-23
  • 打赏
  • 举报
回复
引用 11 楼 NongCunGongLu 的回复:
[quote=引用 10 楼 tcmakebest 的回复:] 这个结果是90800:......
tcmakebest老师,你好!当初结贴太着急,现在发现你的SQL语句写得也是相当有思想,很巧妙。敬佩! 因为贴子已经结了,打算这几天重新开贴给你补分,在此先向你致谢了![/quote] 写的SQL有人能看懂并得到好评我就很高兴了,补分就不必了,谢谢你的诚意,呵!加油
NongCunGongLu 2014-01-23
  • 打赏
  • 举报
回复
引用 10 楼 tcmakebest 的回复:
这个结果是90800:......
tcmakebest老师,你好!当初结贴太着急,现在发现你的SQL语句写得也是相当有思想,很巧妙。敬佩! 因为贴子已经结了,打算这几天重新开贴给你补分,在此先向你致谢了!
tcmakebest 2014-01-23
  • 打赏
  • 举报
回复
这个结果是90800:
declare @t table ( recid int, ioorout int,spid int,dj int,sl int )
insert into @t values (1,1,999,590,120),(2,-1,999,800,110),(3,1,999,580,80)
,(4,-1,999,800,50),(5,1,999,570,100),(6,1,999,560,50),(7,-1,999,800,30)
select sum(case when kucun+sl-subtotal>sl then sl else kucun+sl-subtotal end * dj) from
(	select sl,dj,
	(select SUM(sl) from @t sub where sub.spid=t1.spid and sub.ioorout=1 and sub.recid>=t1.recid) subtotal,
	(select SUM(ioorout*sl) from @t sub2 where sub2.spid=t1.spid) kucun
	from @t t1
	where ioorout=1
) tmp
where kucun+sl-subtotal>0
LongRui888 2014-01-22
  • 打赏
  • 举报
回复
引用 8 楼 NongCunGongLu 的回复:
2005的,老师 最好是SQL语句,不要存储过程
呵呵,写了一个,你试试:
if object_id('[tb]') is not null drop table tb
go 

create table tb(RecId int,    InOrOut int,   spId int,Dj int,Sl int)

insert into tb
select 1 ,         1      ,999      ,590    ,120 union all
select 2 ,        -1      , 999     ,800    ,110 union all
select 3 ,         1      , 999     ,580    ,80 union all
select 4 ,        -1      , 999     ,800    ,50 union all
select 5 ,         1      , 999     ,570    ,100 union all
select 6 ,         1      , 999     ,560    ,50 union all
select 7 ,        -1      , 999     ,800    ,30
go



select spId, sum(xx) as sl
from
(
	select t1.spId,
		   --sum_sl - t2.sl as diff,
		   case when t1.recid = min(t1.RecId) over(partition by t1.spid)
					 then Dj * (sum_sl - isnull(t2.sl,0))
				else Dj*t1.Sl
		   end xx
	from 
	(
		select RecId,
			   spId,
			   Dj,
			   sl,
			   (select SUM(sl) from tb t2 where t1.spId = t2.spId 
				and t1.RecId>= t2.RecId and InOrOut = 1) as sum_sl
		from tb t1
		where InOrOut = 1
	)t1
	left join 
	(
		select spid,sum(sl) sl 
		from tb
		where InOrOut = -1
		group by spId 
	)t2
	  on t1.spId = t2.spId
	where sum_sl - isnull(t2.sl,0) > 0
)t
group by spid
/*
spId	sl
999	90800
*/
NongCunGongLu 2014-01-22
  • 打赏
  • 举报
回复
2005的,老师 最好是SQL语句,不要存储过程
LongRui888 2014-01-22
  • 打赏
  • 举报
回复
引用 6 楼 NongCunGongLu 的回复:
首先感谢楼上几位老师! 我的表达不准确,纠正一下:出库时的价格,是销售价,你们完全可以无视它。出库只影响库存的现存量。 也就是说: RecId InOrOut spId Dj Sl ------------------------------------------ 1 1 999 590 120 此时,库存999商品120件,价值590x120=70800 2 -1 999 (800) (110)此时,库存999商品 10件,价值590x10=5900 3 1 999 580 80 此时,库存999商品 90件,价值5900+580x80=52300 4 -1 999 (800) (50)此时,库存999商品 40件,价值580x40=23200 5 1 999 570 100 此时,库存999商品140件,价值23200+570x100 6 1 999 560 50 此时,库存999商品190件,价值23200+570x100+560x50 7 -1 999 (800) (30)此时,库存999商品160件,价值580x10+570x100+560x50 = 90800 其实最终要的就是这个90800 [quote=引用 2 楼 yupeigu 的回复:] 按照你的需求,查询的结果是什么呢,能贴出来不
yupeigu老师,其实我要的就是一个值:“库中商品现存价值”。按先进先出计算。请老师再看一下...多谢![/quote] 是2000,还是2005的
NongCunGongLu 2014-01-22
  • 打赏
  • 举报
回复
首先感谢楼上几位老师! 我的表达不准确,纠正一下:出库时的价格,是销售价,你们完全可以无视它。出库只影响库存的现存量。 也就是说: RecId InOrOut spId Dj Sl ------------------------------------------ 1 1 999 590 120 此时,库存999商品120件,价值590x120=70800 2 -1 999 (800) (110)此时,库存999商品 10件,价值590x10=5900 3 1 999 580 80 此时,库存999商品 90件,价值5900+580x80=52300 4 -1 999 (800) (50)此时,库存999商品 40件,价值580x40=23200 5 1 999 570 100 此时,库存999商品140件,价值23200+570x100 6 1 999 560 50 此时,库存999商品190件,价值23200+570x100+560x50 7 -1 999 (800) (30)此时,库存999商品160件,价值580x10+570x100+560x50 = 90800 其实最终要的就是这个90800
引用 2 楼 yupeigu 的回复:
按照你的需求,查询的结果是什么呢,能贴出来不
yupeigu老师,其实我要的就是一个值:“库中商品现存价值”。按先进先出计算。请老师再看一下...多谢!
LongRui888 2014-01-22
  • 打赏
  • 举报
回复
if object_id('[tb]') is not null drop table tb
go 

create table tb(RecId int,    InOrOut int,   spId int,Dj int,Sl int)

insert into tb
select 1 ,         1      ,999      ,590    ,120 union all
select 2 ,        -1      , 999     ,800    ,110 union all
select 3 ,         1      , 999     ,580    ,80 union all
select 4 ,        -1      , 999     ,800    ,50 union all
select 5 ,         1      , 999     ,570    ,100 union all
select 6 ,         1      , 999     ,560    ,50 union all
select 7 ,        -1      , 999     ,800    ,30
go


select RecId,
       InOrOut,
       spId,
       InOrOut*dj*sl,
       (select SUM(InOrOut*Dj*Sl) from tb t2 where t1.spid = t2.spId and t2.RecId<=t1.RecId)
from tb t1
  • 打赏
  • 举报
回复
--加减法,更新明细账的结余数量和金额 @sBeginQty和@sBeginSum期初数量和金额,单价=金额/数量。
Create Table #ResStoreAccDet_Sums
(
   GID      varchar(50)    null,
   BeginQty Numeric(18, 6) null,
   BeginSum Numeric(18, 6) null,
   InQty    Numeric(18, 6) null,
   InSum    Numeric(18, 6) null,
   OutQty   Numeric(18, 6) null, 
   OutSum   Numeric(18, 6) null,
   EndQty   Numeric(18, 6) null,
   EndSum  Numeric(18, 6) null)

update #ResStoreAccDet_Sums
set EndQty =(select @sBeginQty +Sum(Isnull(InQty, 0)) -Sum(Isnull(OutQty, 0)) 
             from #ResStoreAccDet_Sums where SID <=t.SID),
    EndSum =(select @sBeginSum +Sum(Isnull(InSum, 0)) -Sum(Isnull(OutSum, 0)) 
            from #ResStoreAccDet_Sums where SID <=t.SID)
 from #ResStoreAccDet_Sums t
shoppo0505 2014-01-22
  • 打赏
  • 举报
回复
select spid, SUM(SI*InOrOut) AS SL, SUM(DJ*SI*InOrOut) AS Value from tb group by spid
LongRui888 2014-01-22
  • 打赏
  • 举报
回复
按照你的需求,查询的结果是什么呢,能贴出来不
  • 打赏
  • 举报
回复
做移动平均加权,简单很多。
王中王羽毛球馆管理软件介绍 一、简介 王中王羽毛球馆管理软件也称【羽毛球管理软件】【羽毛球管理系统】【羽毛球馆管理系统】【羽毛球馆管理软件】【羽毛球馆收费软件】【羽毛球馆计费软件】是一套用于羽毛球馆、羽毛球场、体育馆、网球馆、台球厅等体育场馆的专业优秀的电脑收费管理系统。该系统采用先进的dotnet开发技术,结合国内先进的管理思想和管理方,历经2年开发而成。集POS收银收费管理,场地租金分时段分场地计费管理,场地预订,会员管理,短信预定管理、灯光控制、语音交互等强大功能为一身。能够有效的杜绝管理上的漏洞,使客户和经营者的联系更加紧密减少客户的流失,大幅度降低管理工作的工作量, 降低服务员的劳动强度节约成本,使您的经营管理变得轻松简单。持卡消费真正让客户感受到球馆的档次. 本系统适合于以下场馆使用:羽毛球馆,乒乓球馆,体育馆、体育中心,网球馆,保龄球馆, 沙狐球馆, 台球馆, 高尔夫馆, 瑜伽馆 馆,武术馆馆, 泰拳道馆馆,柔道馆馆, 健身房馆,游泳馆, 溜冰场馆,篮球场馆,足球场馆, 射击场馆, 卡丁车场馆, 滑雪场馆,潜水俱乐部馆等等 下图为自定义界面全屏显示: 二、管理特色: 王中王羽毛球管理软件跟国内其他同类相比,最大的特点是采用独创的价格规则来定义场地价格,使场地价格定义方式灵活、强大、操作非常简单。可以实现任意的您能想到的优惠方案,而设置时只需要增加一条价格规则。不像其他软件,您需要对每个场地不同时间,输入不同的价格,输到你头昏。其他的特点下面依次展开论述。 2.1场地价格定义灵活方便、功能强大。 系统出厂时已经设置了定价规则。用户可以自定义定价规则。定价规则有四个要素: ? 客户 (可以指定为全部、会员、非会员、或者通过公式指定的一部分会员) ? 场地 (可以指定全部场地、一类场地,比如羽毛球场、或者其中的几片场地、一片场地) ? 时间:可以指定为全部时间,或者部分时间:比如节假日、春节、五一、十一 ? 周末,选择时间非常方便 ? 价格,支持按小时或者按次计费缺省一次是2小时,可以参数设置一次的长短 系统可以建立无数个定价规则,规则有优先级别,级别高的规则起作用,这样理论上系统可以实现无穷个价格方案,而付出的成本却是异常低廉的,这为经营者发挥营销才能 提供了物质基础。举个例子:老板说,我要实现“过生日的会员在每天下午6点到7点打球只要10元/小时”,试问国内那个软件可以实现?而我们可以轻松实现。 您也许会说,定价规则很复杂,我不会使用怎么办?您放心。定价规则可以方便导入导出,如果您不懂设置价格规则,我们可以帮助你设置,然后把价格规则发送给你,使您解除后顾之忧。同时系统里内置规则中实现了多种收费标准,您可以随意选择使用。 2.2商品折扣定义方便灵活。 商品折扣支持简单折扣和复杂折扣。 简单折扣只要定义每个商品的会员价和零售价。 复杂折扣可以根据 时间【平时,闲时,白天、晚上】 客人【所以人,会员、非会员、一部分会员】 商品【全部商品、部分商品、部分商品类别】 数量的不同而使用不同的折扣。可以方便的实现开业优惠、节日促销。 可以实现的典型的优惠方案: 开业五折优惠 购买可口可乐5瓶以上10瓶以内打8折 金卡会员晚上8点到10点购买脉动可以达8.6折。 2.3场地预定简单、方便。 系统支持临时、每日、每周三种类型的预定,每日、每周预订只要录入一次、到时间会自动显示在界面上、场地的状态图会自动显示场地已经被预订、过了预订时间后场地的状态又会自动还原。提供史上最强大的图形查询界面,可以按日、按周、按月查询预订信息。预订人可以临时取消不来,操作灵活。支持球票管理,出售球票时自动产生预订。开场时无需付款. 2.4界面美观大方全键盘操作 (不用鼠标也能操作),多达26多种皮肤,100%满足您的个性要。 2.5强大的优惠卡管理功能。 支持四种类型的优惠卡。 按次计算的优惠卡:比如300元10次卡(每次1小时) 按时间计算的优惠卡 :比如500元20小时卡, 现金充值卡:面值1000元,售价800元,相当于打八折 包时卡:如:包打一年1000元 支持优惠卡新卡登记、优惠卡销售、优惠卡充值功能。 2.6强大的会员管理 支持会员照片、支持摄像头照相。 支持会员充值、转账 会员消费查询 会员密码,设置密码后,不用带卡也可以消费 支持会员组概念,系统提供了很多公式,可以方便快速 对会员分组,比如: 20岁以上50以下会员 积分大于1000的会员 今天过生日的会员 累计消费超过10000元的会员 余额超过5000元的会员 入会超过2年的老顾客 通过分组,可以实现复杂的收费规则,而实现起来却非常简单 会员卡支持磁卡、ID卡、IC卡、MF1卡(非接触IC卡)多种介质 目前支持深圳方卡M1读卡机,常州银联M
王中王体育馆管理软件介绍 一、简介 王中王体育馆管理软件也称【羽毛球管理软件】【羽毛球管理系统】【羽毛球馆管理系统】【羽毛球馆管理软件】【羽毛球馆收费软件】【羽毛球馆计费软件】是一套用于羽毛球馆、羽毛球场、体育馆、网球馆、台球厅等体育场馆的专业优秀的电脑收费管理系统。该系统采用先进的dotnet开发技术,结合国内先进的管理思想和管理方,历经2年开发而成。集POS收银收费管理,场地按时计费管理,优惠卡管理,场地管理、场地预订,会员管理,等强大功能为一身。能够有效的杜绝管理上的漏洞,使客户和经营者的联系更加紧密减少客户的流失,大幅度降低管理工作的工作量, 降低服务员的劳动强度节约成本,使您的经营管理变得轻松简单。持卡消费真正让客户感受到球馆的档次 二、管理特色: 王中王羽毛球管理软件跟国内其他同类相比,最大的特点是采用独创的价格规则来定义场地价格,使场地价格定义方式灵活、强大、操作非常简单。可以实现任意的您能想到的优惠方案,而设置时只需要增加一条价格规则。不像其他软件,您需要对每个场地不同时间,输入不同的价格,输到你头昏。其他的特点下面依次展开论述。 2.1场地价格定义灵活方便、功能强大。 系统出厂时已经设置了定价规则。用户可以自定义定价规则。定价规则有四个要素: ? 客户 (可以指定为全部、会员、非会员、或者通过公式指定的一部分会员) ? 场地 (可以指定全部场地、一类场地,比如羽毛球场、或者其中的几片场地、一片场地) ? 时间:可以指定为全部时间,或者部分时间:比如节假日、春节、五一、十一 ? 周末,选择时间非常方便 ? 价格,支持按小时或者按次计费缺省一次是2小时,可以参数设置一次的长短 系统可以建立无数个定价规则,规则有优先级别,级别高的规则起作用,这样理论上系统可以实现无穷个价格方案,而付出的成本却是异常低廉的,这为经营者发挥营销才能 提供了物质基础。举个例子:老板说,我要实现“过生日的会员在每天下午6点到7点打球只要10元/小时”,试问国内那个软件可以实现?而我们可以轻松实现。 您也许会说,定价规则很复杂,我不会使用怎么办?您放心。定价规则可以方便导入导出,如果您不懂设置价格规则,我们可以帮助你设置,然后把价格规则发送给你,使您解除后顾之忧。同时系统里内置规则中实现了多种收费标准,您可以随意选择使用。 2.2场地预定简单、方便。 系统支持临时、每日、每周三种类型的预定,每日、每周预订只要录入一次、到时间会自动显示在界面上、场地的状态图会自动显示场地已经被预订、过了预订时间后场地的状态又会自动还原。 2.3界面美观大方全键盘操作 (不用鼠标也能操作),多达26多种皮肤,100%满足您的个性要。 2.4强大的优惠卡管理功能。 支持四种类型的优惠卡。 按次计算的优惠卡:比如300元10次卡(每次1小时) 按时间计算的优惠卡 :比如500元20小时卡, 现金充值卡:面值1000元,售价800元,相当于打八折 包时卡:如:包打一年1000元 支持优惠卡新卡登记、优惠卡销售、优惠卡充值功能。 2.5强大的会员管理 支持会员照片、支持摄像头照相。 支持会员充值、转账 会员消费查询 会员密码,设置密码后,不用带卡也可以消费 支持会员组概念,系统提供了很多公式,可以方便快速 对会员分组,比如: 50岁以上会员 20岁以上50以下会员 20岁以下会员 积分大于100的会员 积分大于1000的会员 今天过生日的会员 累计消费超过10000元的会员 余额超过5000元的会员 入会超过2年的老顾客 通过分组,可以实现复杂的收费规则,而实现起来却非常简单 会员卡支持磁卡、ID卡、IC卡、MF1卡(非接触IC卡)多种介质 目前支持深圳方卡M1读卡机,常州银联M1读卡机其他类型的读卡机 在不断增加。 2.6支持POS销售商品。 支持商品的条码管理,支持入库,销售,库存等,可按照商品上的条码建立商品信息,销售时直接用条码扫描枪进行扫描,方便快速;支持LED客户显示屏,方便客户 2.7可以打印多种小票 开场单、结账单、售卡单、充值单、会员转账单。 是否打印可以参数设置 2.8定时提醒功能。 支持预订到达前30(可以设置)分钟每1(可以设置)分种提示一次 场地到时退场提醒,也支持设置提前时间,频率。 提示方式多样,会出现小老人,同时状态栏出现信息图标。 支持声音提示 2.9两种收费方式。 普通【租场后付款】 预付【租场前付款】 2.10直观的场地状态图 场地图形化,完善强大的tooltip功能 场地状态图以不同的图形显示:占用、预订、已付款、停用、空闲五种状态。 场地时序图以另外一个视角显示场地占用情况,可以清楚的看到那些场地的利用效率高、那些效率低。 自定义场地状态图,可以自己设定场地的行列位置,可以设置显示的图形(木地板还

34,591

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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