我有以下数据,需要使用前面每行的数量来计算每行的运行平均值。
Option Explicit
Dim BigOne As BigClass
Private Sub Class_Initialize()
Set BigOne = New BigClass
End Sub
Private Sub Class_Terminate()
Set BigOne = Nothing
End Sub
Property Let var3(v As Integer)
BigOne.var3 = v
End Property
Property Get var3() As Integer
var3 = BigOne.var3
End Property
预期结果
CREATE TABLE [dbo].[AKTest](
[IntakeSellingPrice] [decimal](38, 20) NULL,
[IntakeSellingAmount] [decimal](38, 6) NULL,
[Item No_] [nvarchar](20) NOT NULL,
[Variant Code] [nvarchar](10) NOT NULL,
[Unit of Measure Code] [nvarchar](10) NOT NULL,
[Posting Date] [datetime] NOT NULL,
[PurchaseQty] [decimal](38, 20) NULL,
[ReceiptNo] [bigint] NULL,
[InventoryBalance] [decimal](38, 20) NOT NULL,
[NewBalance] [decimal](38, 20) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[AKTest] ([IntakeSellingPrice], [IntakeSellingAmount], [Item No_], [Variant Code], [Unit of Measure Code], [Posting Date], [PurchaseQty], [ReceiptNo], [InventoryBalance], [NewBalance]) VALUES (CAST(10.00000000000000000000 AS Decimal(38, 20)), CAST(1000.000000 AS Decimal(38, 6)), N'1000001', N'NO_SIZE', N'EACH', CAST(0x0000A80800000000 AS DateTime), CAST(100.00000000000000000000 AS Decimal(38, 20)), 1, CAST(0.00000000000000000000 AS Decimal(38, 20)), CAST(100.00000000000000000000 AS Decimal(38, 20)))
GO
INSERT [dbo].[AKTest] ([IntakeSellingPrice], [IntakeSellingAmount], [Item No_], [Variant Code], [Unit of Measure Code], [Posting Date], [PurchaseQty], [ReceiptNo], [InventoryBalance], [NewBalance]) VALUES (CAST(5.00000000000000000000 AS Decimal(38, 20)), CAST(250.000000 AS Decimal(38, 6)), N'1000001', N'NO_SIZE', N'EACH', CAST(0x0000A80E00000000 AS DateTime), CAST(50.00000000000000000000 AS Decimal(38, 20)), 2, CAST(50.00000000000000000000 AS Decimal(38, 20)), CAST(100.00000000000000000000 AS Decimal(38, 20)))
GO
INSERT [dbo].[AKTest] ([IntakeSellingPrice], [IntakeSellingAmount], [Item No_], [Variant Code], [Unit of Measure Code], [Posting Date], [PurchaseQty], [ReceiptNo], [InventoryBalance], [NewBalance]) VALUES (CAST(12.50000000000000000000 AS Decimal(38, 20)), CAST(625.000000 AS Decimal(38, 6)), N'1000001', N'NO_SIZE', N'EACH', CAST(0x0000A81900000000 AS DateTime), CAST(50.00000000000000000000 AS Decimal(38, 20)), 3, CAST(60.00000000000000000000 AS Decimal(38, 20)), CAST(110.00000000000000000000 AS Decimal(38, 20)))
GO
我以前手动计算的Formular定义如下第三行。如果你先从底部开始,计算会更好。
A)我从使用receiptNo 3的底部开始,其中NewBalance是110。
B)购买50个单位,12.50 = 625
离开60个单位的C)在前一行中购买50个单位,用于5 = 250D)留下10个单位。在上一行中购买100个单位,10 = 1000.但我们只需要10的成本,所以1000/10 = 100。
E)将所有费用加起来625 + 250 + 100 = 975/110 = 8.86
答案 0 :(得分:2)
我不认为使用ROWS BETWEEN
和OVER
这是可能的,因为逻辑有点奇怪?
我创建了一个临时表来播放数据并测试结果,但基本上这只是添加了递归CTE的原始脚本:
CREATE TABLE #AKTest (
[IntakeSellingPrice] [decimal](38, 20) NULL,
[IntakeSellingAmount] [decimal](38, 6) NULL,
[Item No_] [nvarchar](20) NOT NULL,
[Variant Code] [nvarchar](10) NOT NULL,
[Unit of Measure Code] [nvarchar](10) NOT NULL,
[Posting Date] [datetime] NOT NULL,
[PurchaseQty] [decimal](38, 20) NULL,
[ReceiptNo] [bigint] NULL,
[InventoryBalance] [decimal](38, 20) NOT NULL,
[NewBalance] [decimal](38, 20) NULL);
GO
INSERT #AKTest ([IntakeSellingPrice], [IntakeSellingAmount], [Item No_], [Variant Code], [Unit of Measure Code], [Posting Date], [PurchaseQty], [ReceiptNo], [InventoryBalance], [NewBalance]) VALUES (CAST(10.00000000000000000000 AS Decimal(38, 20)), CAST(1000.000000 AS Decimal(38, 6)), N'1000001', N'NO_SIZE', N'EACH', CAST(0x0000A80800000000 AS DateTime), CAST(100.00000000000000000000 AS Decimal(38, 20)), 1, CAST(0.00000000000000000000 AS Decimal(38, 20)), CAST(100.00000000000000000000 AS Decimal(38, 20)))
GO
INSERT #AKTest ([IntakeSellingPrice], [IntakeSellingAmount], [Item No_], [Variant Code], [Unit of Measure Code], [Posting Date], [PurchaseQty], [ReceiptNo], [InventoryBalance], [NewBalance]) VALUES (CAST(5.00000000000000000000 AS Decimal(38, 20)), CAST(250.000000 AS Decimal(38, 6)), N'1000001', N'NO_SIZE', N'EACH', CAST(0x0000A80E00000000 AS DateTime), CAST(50.00000000000000000000 AS Decimal(38, 20)), 2, CAST(50.00000000000000000000 AS Decimal(38, 20)), CAST(100.00000000000000000000 AS Decimal(38, 20)))
GO
INSERT #AKTest ([IntakeSellingPrice], [IntakeSellingAmount], [Item No_], [Variant Code], [Unit of Measure Code], [Posting Date], [PurchaseQty], [ReceiptNo], [InventoryBalance], [NewBalance]) VALUES (CAST(12.50000000000000000000 AS Decimal(38, 20)), CAST(625.000000 AS Decimal(38, 6)), N'1000001', N'NO_SIZE', N'EACH', CAST(0x0000A81900000000 AS DateTime), CAST(50.00000000000000000000 AS Decimal(38, 20)), 3, CAST(60.00000000000000000000 AS Decimal(38, 20)), CAST(110.00000000000000000000 AS Decimal(38, 20)))
GO
SELECT * FROM #AKTest;
WITH cte AS (
SELECT
ReceiptNo,
ReceiptNo AS linked_to,
NewBalance,
NewBalance - PurchaseQty AS remaining,
PurchaseQty AS purchased,
IntakeSellingPrice
FROM
#AKTest
UNION ALL
SELECT
c.ReceiptNo,
c.linked_to - 1 AS linked_to,
a.NewBalance,
c.remaining - a.PurchaseQty AS remaining,
CASE WHEN a.PurchaseQty > c.remaining THEN c.remaining ELSE a.PurchaseQty END AS purchased,
a.IntakeSellingPrice
FROM
cte c
INNER JOIN #AKTest a ON a.ReceiptNo = c.linked_to - 1
WHERE
c.linked_to > 1)
SELECT
ReceiptNo,
SUM(purchased * IntakeSellingPrice) / MAX(NewBalance) AS avg_price
FROM
cte
GROUP BY
ReceiptNo
ORDER BY
ReceiptNo;
获取正确答案:
ReceiptNo avg_price
1 10.000000
2 7.500000
3 8.863636
根据要求,这将显示表格中的所有数据,最终的平均价格为:
WITH cte AS (
SELECT
ReceiptNo,
ReceiptNo AS linked_to,
NewBalance,
NewBalance - PurchaseQty AS remaining,
PurchaseQty AS purchased,
IntakeSellingPrice
FROM
#AKTest
UNION ALL
SELECT
c.ReceiptNo,
c.linked_to - 1 AS linked_to,
a.NewBalance,
c.remaining - a.PurchaseQty AS remaining,
CASE WHEN a.PurchaseQty > c.remaining THEN c.remaining ELSE a.PurchaseQty END AS purchased,
a.IntakeSellingPrice
FROM
cte c
INNER JOIN #AKTest a ON a.ReceiptNo = c.linked_to - 1
WHERE
c.linked_to > 1),
Averages AS (
SELECT
ReceiptNo,
SUM(purchased * IntakeSellingPrice) / MAX(NewBalance) AS avg_price
FROM
cte
GROUP BY
ReceiptNo)
SELECT
a.*,
v.avg_price
FROM
Averages v
INNER JOIN #AKTest a ON a.ReceiptNo = v.ReceiptNo
ORDER BY
a.ReceiptNo;