我正在使用Microsoft SQL Server 2012。
我有一个包含项目交易的表格:
artcode transdate Qty transactionvalue
------------------------------------------------
M100 2010-11-24 6.00 179.40
M100 2010-11-24 -6.00 -179.4
M100 2010-11-25 100.00 2900.00
M100 2010-11-26 -1.00 -29
M100 2010-11-26 -5.00 -145
M100 2010-11-26 -1.00 -29
M100 2010-11-29 -5.00 -145
M100 2010-11-29 -3.00 -87
M100 2010-11-29 -1.00 -29
通过此查询,我设法以运行顺序获取累积值:
SELECT
TransDate, ArtCode, CumulativeQuantity, CumulativeValue
FROM
(SELECT
ArtCode,
SUM(CAST(REPLACE(REPLACE(NULLIF(Qty, ''), ',', '.'), ' ', '') AS float)) OVER (PARTITION BY artcode ORDER BY transdate) AS CumulativeQuantity,
SUM(CAST(REPLACE(REPLACE(NULLIF(TotCostPrice, ''), ',', '.'), ' ', '') AS FLOAT)) OVER (PARTITION BY artcode ORDER BY transdate) AS CumulativeValue,
TransDate
FROM
stage_itemhistory
WHERE
artcode = 'm100' AND stockaffect = 1) S
GROUP BY
TransDate, ArtCode, CumulativeQuantity, CumulativeValue
返回:
TransDate ArtCode CumulativeQuantity CumulativeValue
--------------------------------------------------------
2010-11-24 M100 0 0
2010-11-25 M100 100 2900
2010-11-26 M100 93 2697
2010-11-29 M100 84 2436
这与我所追求的非常接近,唯一缺少的是日期之间的日期,即之前的日期累计值。所以它看起来像这样:
TransDate ArtCode CumulativeQuantity CumulativeValue
--------------------------------------------------------
2010-11-24 M100 0 0
2010-11-25 M100 100 2900
2010-11-26 M100 93 2697
2010-11-27 M100 93 2697
2010-11-28 M100 93 2697
2010-11-29 M100 84 2436
任何和所有帮助将不胜感激!提前谢谢。
答案 0 :(得分:1)
这比我想象的要难。有人可能会有一个更简单的解决方案。需要填写艺术代码并考虑不同艺术代码的不同范围。
declare @T table (artcode varchar(10), transdate date, Qty smallmoney, transactionvalue smallmoney);
insert into @T values
('M100', '2010-11-24', 6.00, 179.40)
, ('M100', '2010-11-24', -6.00, -179.4)
, ('M100', '2010-11-25', 100.00, 2900.00)
, ('M100', '2010-11-26', -1.00, -29)
, ('M100', '2010-11-26', -5.00, -145)
, ('M100', '2010-11-26', -1.00, -29)
, ('M100', '2010-11-29', -5.00, -145)
, ('M100', '2010-11-29', -3.00, -87)
, ('M100', '2010-11-29', -1.00, -29)
, ('M101', '2010-11-23', 6.00, 179.40)
, ('M101', '2010-11-25', 100.00, 2900.00)
, ('M101', '2010-11-26', -1.00, -29)
, ('M101', '2010-11-26', -5.00, -145)
, ('M101', '2010-11-26', -1.00, -29)
, ('M101', '2010-11-30', -5.00, -145)
, ('M101', '2010-11-30', -3.00, -87)
, ('M101', '2010-11-30', -1.00, -29);
with limits as
( select t.artcode, min(t.transdate) as startDate, max(t.transdate) as endtDate
from @T t
group by t.artcode
)
, dts as
( select l.artcode, l.startDate as dt, l.startDate, l.endtDate
from limits l
union all
select l.artcode, dateadd(day, 1, l.dt), l.startDate, l.endtDate
from dts l
where dateadd(day, 1, l.dt) <= l.endtDate
)
select distinct dts.artcode, dts.dt
, sum(isnull(t.Qty, 0)) over (partition by dts.artcode order by dts.dt) as Qty
, sum(isnull(t.transactionvalue, 0)) over (partition by dts.artcode order by dts.dt) as transactionvalue
from dts
left join @T t
on t.transdate = dts.dt
and t.artcode = dts.artcode
order by dts.artcode, dts.dt;
artcode dt Qty transactionvalue
---------- ---------- --------------------- ---------------------
M100 2010-11-24 0.00 0.00
M100 2010-11-25 100.00 2900.00
M100 2010-11-26 93.00 2697.00
M100 2010-11-27 93.00 2697.00
M100 2010-11-28 93.00 2697.00
M100 2010-11-29 84.00 2436.00
M101 2010-11-23 6.00 179.40
M101 2010-11-24 6.00 179.40
M101 2010-11-25 106.00 3079.40
M101 2010-11-26 99.00 2876.40
M101 2010-11-27 99.00 2876.40
M101 2010-11-28 99.00 2876.40
M101 2010-11-29 99.00 2876.40
M101 2010-11-30 90.00 2615.40
答案 1 :(得分:0)
解决这个问题的方法是使用CTE一年中的所有日子(或所需的时间跨度),然后适当地使用left join
,如下所示:
with Calendar as (
select CAST('2010-01-01' as date) [transdate], 0 [Qty], 0 [transactionvalue]
union all
select DATEADD(DAY, 1, [transdate]), 0, 0 from Calendar
where [transdate] < '2010-12-31'
), with Calendar2 ([artcode], [transdate], [Qty], [transactionvalue]) as (
select [T].artcode, [C].* from Calendar [C]
cross join (select distinct artcode from MY_TABLE) [T]
)
select [a].[artcode], [a].[transdate], isnull([b].[Qty],[a].[Qty]),isnull([b].[transactionvalue],[a].[transactionvalue]) from Calendar2 [a]
left join MY_TABLE [b] on ([a].transdate = [b].transdate and [a].[artcode] = [b].[artocde])
option(maxrecursion 0)
答案 2 :(得分:0)
如果您没有日历或计数表,则可以使用临时计数表
另外,假设用ArdCode划分
示例强>
;with cte as (
SELECT
TransDate, ArtCode, CumulativeQuantity, CumulativeValue
FROM
(SELECT
ArtCode,
SUM(CAST(REPLACE(REPLACE(NULLIF(Qty, ''), ',', '.'), ' ', '') AS float)) OVER (PARTITION BY artcode ORDER BY transdate) AS CumulativeQuantity,
SUM(CAST(REPLACE(REPLACE(NULLIF(TotCostPrice, ''), ',', '.'), ' ', '') AS FLOAT)) OVER (PARTITION BY artcode ORDER BY transdate) AS CumulativeValue,
TransDate
FROM
stage_itemhistory
WHERE
artcode = 'm100' AND stockaffect = 1) S
GROUP BY
TransDate, ArtCode, CumulativeQuantity, CumulativeValue
)
Select TransDate = B.D
,A.ArtCode
,A.CumulativeQuantity
,A.CumulativeValue
From (
Select *
,NextDate = lead([TransDate],1,dateadd(day,1,[TransDate])) over (partition by ArtCode order by [TransDate])
From cte
) A
Cross Apply (
Select Top (DateDiff(DAY,[TransDate],NextDate)) D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),[TransDate]) From master..spt_values n1,master..spt_values n2
) B
返回
TransDate ArtCode CumulativeQuantity CumulativeValue
2010-11-24 M100 0 0
2010-11-25 M100 100 2900
2010-11-26 M100 93 2697
2010-11-27 M100 93 2697
2010-11-28 M100 93 2697
2010-11-29 M100 84 2436
答案 3 :(得分:-1)
我找到了一个适合我的解决方案:
--Create TempTable
CREATE TABLE #TempTable(
TransDate Date,
ArtCode varchar(150),
CumulativeQuantity float(53),
CumulativeValue float(53))
--Insert Cumulative data, still missing dates
insert into #TempTable (TransDate, ArtCode, CumulativeQuantity, CumulativeValue)
SELECT TransDate, ArtCode, CumulativeQuantity, CumulativeValue FROM (
select ArtCode,
SUM(Qty) OVER (partition by artcode order by transdate) AS CumulativeQuantity,
SUM(TotCostPrice) OVER (partition by artcode order by transdate) AS CumulativeValue,
TransDate
from stage_itemhistory where stockaffect=1
) S
group by TransDate, ArtCode, CumulativeQuantity, CumulativeValue;
--Select all with Missing dates with previous dates data
WITH CTE as (
SELECT TransDate, ArtCode, CumulativeQuantity, CumulativeValue FROM #TempTable
UNION ALL
select DATEADD(Day,1,TransDate), ArtCode, CumulativeQuantity, CumulativeValue FROM CTE e
Where Not Exists (select * from #TempTable e2 where e2.TransDate = DATEADD(DAY,1,e.TransDate) and e.ArtCode=e2.ArtCode)
and TransDate < GETDATE()
)
select TransDate,
ArtCode,
CumulativeQuantity,
ROUND(CumulativeValue,2)
from CTE where TransDate > '2016-01-01'
Order by ArtCode, TransDate
OPTION (MAXRECURSION 0)