用計(jì)算列實(shí)現(xiàn)移動(dòng)加權(quán)平均算法
if OBJECT_ID('tb') is not null drop table tb
if OBJECT_ID('TEMP') is not null drop table TEMP
if OBJECT_ID('FUN_NOWPRICE') is not null drop FUNCTION FUN_NOWPRICE
if OBJECT_ID('FUN_NOWQTY') is not null drop FUNCTION FUN_NOWQTY
go
create table tb(
id INT
,Date1 datetime
,ctype varchar(10)
,qnt float
,pri float
)
--qnt 數(shù)量
--pri 單價(jià)
insert tb
select 0,'2009-1-1', '進(jìn)貨', 10, 100 union all
select 1,'2009-1-1', '進(jìn)貨', 50, 120 union all
select 2,'2009-1-2', '出貨', 30, 150 union all
select 3,'2009-1-3', '進(jìn)貨', 40, 130 union all
select 4,'2009-1-3', '出貨', 25, 160
GO
-- 我要算成本價(jià),按移動(dòng)加權(quán)平均
/*
1進(jìn)貨以后的成本價(jià)c1=(10*100+50*120)/(10+50)
2出貨以后的成本價(jià)c2=((10+50)*c1-30*c1)/((10+50)-30)=C2
--也就是說(shuō)出貨的時(shí)候價(jià)格不變
3進(jìn)貨以后的成本價(jià)c3=(((10+50)-30)*c2+40*130)/((10+50)-30+40)
--也就是說(shuō)進(jìn)貨的時(shí)候單價(jià)更新為(當(dāng)前庫(kù)存的總價(jià)值+庫(kù)總價(jià)值)/入庫(kù)后總數(shù)量
以此類推...
*/
--想了半天,覺(jué)得只能用循環(huán)、遞歸、游標(biāo)實(shí)現(xiàn),因?yàn)槌鰩?kù)時(shí)的價(jià)格是根據(jù)之前的記錄算出來(lái)的。
--也許有經(jīng)典的算法,誰(shuí)知道的麻煩教教我或者發(fā)個(gè)鏈接。
--這個(gè)FUNCTION就是變相實(shí)現(xiàn)遞歸的
CREATE FUNCTION FUN_NOWPRICE(@ID INT)
RETURNS NUMERIC(19,6)
AS
BEGIN
RETURN (SELECT ISNULL(NOWPRICE,0) FROM
(SELECT MAX(NOWPRICE) 'NOWPRICE' FROM TEMP T1 WHERE ID<@ID AND
NOT EXISTS(SELECT 1 FROM TEMP WHERE ID>T1.ID AND ID<@ID))
T)
END
GO
--這個(gè)FUNCTION是為了計(jì)算方便
CREATE FUNCTION FUN_NOWQTY(@ID INT)
RETURNS NUMERIC(19,6)
AS
BEGIN
RETURN (SELECT ISNULL(SUM(CASE CTYPE WHEN '進(jìn)貨' THEN QNT ELSE 0-QNT END),0) FROM TEMP WHERE ID<@ID)
END
GO
--建一個(gè)臨時(shí)表,包含原表參與運(yùn)算的全部字段
create table TEMP(
id INT
,Date1 datetime
,ctype varchar(10)
,qnt float
,pri float
,NOWPRICE AS
CASE ctype
WHEN '出貨' THEN DBO.FUN_NOWPRICE(ID)
ELSE (DBO.FUN_NOWPRICE(ID)*DBO.FUN_NOWQTY(ID)+QNT*PRI)/(DBO.FUN_NOWQTY(ID)+QNT)
END)
INSERT INTO TEMP
SELECT * FROM TB
ORDER BY DATE1 ASC,ID ASC
SELECT * FROM TEMP
/*
0 2009-01-01 00:00:00.000 進(jìn)貨 10 100 100
1 2009-01-01 00:00:00.000 進(jìn)貨 50 120 116.666666666667
2 2009-01-02 00:00:00.000 出貨 30 150 116.666667
3 2009-01-03 00:00:00.000 進(jìn)貨 40 130 124.285714428571
4 2009-01-03 00:00:00.000 出貨 25 160 124.285714
*/
這個(gè)寫(xiě)法的不完善處在于它是根據(jù)ID和日期對(duì)記錄進(jìn)行排序的,對(duì)于同一天的出入庫(kù)情況沒(méi)有處理。實(shí)際運(yùn)用中可以根據(jù)CREATEDATE等時(shí)間標(biāo)志性字段來(lái)進(jìn)行排序。
--------------------------------------------------------------------------------
第一次寫(xiě)技術(shù)性博客,希望這是一個(gè)好的開(kāi)始,歡迎大家對(duì)我的算法進(jìn)行指正^_^
相關(guān)文章
執(zhí)行Insert Exec時(shí)的隱藏開(kāi)銷 分析
Insert Exec時(shí)的隱藏開(kāi)銷,大家可以參考下。2009-07-07推薦Sql server一些常見(jiàn)性能問(wèn)題的解決方法
具體的SQL語(yǔ)句在很多情況下需要結(jié)合實(shí)際的應(yīng)用情況來(lái)寫(xiě),這里不作敘述。2008-08-08SQL數(shù)據(jù)庫(kù)與oracle數(shù)據(jù)庫(kù)鏡像有什么不同對(duì)比
數(shù)據(jù)庫(kù)鏡像是將數(shù)據(jù)庫(kù)事務(wù)處理從一個(gè)數(shù)據(jù)庫(kù)移動(dòng)到不同環(huán)境中的另一個(gè)數(shù)據(jù)庫(kù)中。鏡像的拷貝是一個(gè)備用的拷貝,不能直接訪問(wèn),它只用在錯(cuò)誤恢復(fù)的情況下。2010-03-03淺談數(shù)據(jù)庫(kù)緩存最終一致性的四種方案
緩存是軟件開(kāi)發(fā)中一個(gè)非常有用的概念,數(shù)據(jù)庫(kù)緩存更是在項(xiàng)目中必然會(huì)遇到的場(chǎng)景,緩存一致性的保證,更是在面試中被反復(fù)問(wèn)到。下面我們就一起來(lái)了解一下2021-04-04解決Navicat Premium 12連接Oracle時(shí)提示oracle library is not loaded的
這篇文章主要介紹了解決Navicat Premium 12連接Oracle時(shí)提示oracle library is not loaded的問(wèn)題,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12數(shù)據(jù)庫(kù)之SQL注入原理以及過(guò)程的簡(jiǎn)單介紹
這篇文章主要介紹了數(shù)據(jù)庫(kù)之SQL注入原理以及過(guò)程的簡(jiǎn)單介紹,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07數(shù)據(jù)庫(kù)插入數(shù)據(jù)之select into from與insert into select區(qū)別詳解
能第一次接觸select...into...from...和insert into...select...有很多人都會(huì)誤解, 從表面上看都是把相關(guān)信息查詢出來(lái),然后添加到一個(gè)表里,其實(shí)還遠(yuǎn)遠(yuǎn)沒(méi)有這么簡(jiǎn)單,接下來(lái),小豬就用最普通的表述給大家介紹一下這兩者間的區(qū)別2014-01-01