T-Sql使用递归CTE计算平均值

问题描述 投票:0回答:1

我有下表,并构建了一个递归CTE查询,计算特定[项目号]和第一张收据的股票平均价格,并使用该平均值计算后续平均值i / e收据2,收据3直到它结束。

如果项目只有一组记录,则此方法很有用。例如项目号2000045(收据1,2,3等)。但是,如果我有一个多项目的表没有和收据没有这个查询不会工作。有人建议我使用光标迭代项目编号,但不确定。请帮忙。

CREATE TABLE [dbo].[AKTest](
[IntakeSellingPrice] [decimal](38, 20) NULL,
[IntakeSellingAmount] [decimal](38, 6) NULL,
[Item No_] [nvarchar](20) 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_], [Posting Date], [PurchaseQty], [ReceiptNo], [InventoryBalance], [NewBalance]) VALUES (CAST(75.00000000000000000000 AS Decimal(38, 20)), CAST(37500.000000 AS Decimal(38, 6)), N'2000045', CAST(0x0000A81F00000000 AS DateTime), CAST(500.00000000000000000000 AS Decimal(38, 20)), 1, CAST(0.00000000000000000000 AS Decimal(38, 20)), CAST(500.00000000000000000000 AS Decimal(38, 20)))
GO
INSERT [dbo].[AKTest] ([IntakeSellingPrice], [IntakeSellingAmount], [Item No_], [Posting Date], [PurchaseQty], [ReceiptNo], [InventoryBalance], [NewBalance]) VALUES (CAST(75.00000000000000000000 AS Decimal(38, 20)), CAST(163575.000000 AS Decimal(38, 6)), N'2000045', CAST(0x0000A82400000000 AS DateTime), CAST(2181.00000000000000000000 AS Decimal(38, 20)), 2, CAST(500.00000000000000000000 AS Decimal(38, 20)), CAST(2681.00000000000000000000 AS Decimal(38, 20)))
GO
INSERT [dbo].[AKTest] ([IntakeSellingPrice], [IntakeSellingAmount], [Item No_], [Posting Date], [PurchaseQty], [ReceiptNo], [InventoryBalance], [NewBalance]) VALUES (CAST(83.33000000000000000000 AS Decimal(38, 20)), CAST(55.555831 AS Decimal(38, 6)), N'2000045', CAST(0x0000A82B00000000 AS DateTime), CAST(0.66667000000000000000 AS Decimal(38, 20)), 3, CAST(2681.00000000000000000000 AS Decimal(38, 20)), CAST(2681.66667000000000000000 AS Decimal(38, 20)))
GO



;WITH   Testcte
AS     (
SELECT A.*, (
                (A.PurchaseQty * A.IntakeSellingPrice) 
                    + 
                    (A.InventoryBalance *  isnull(A2.IntakeSellingPrice, A.IntakeSellingPrice))
                ) /A.NewBalance [RunningAVG]

    from AKTest A
    left join AKTest A2 on A.[Item No_] = A2.[Item No_] and A.ReceiptNo = A2.ReceiptNo +1
    where A.ReceiptNo = 1 -- anchor member
    and A.[Item No_]='2000045'

UNION ALL

SELECT X.* , (
            (X.PurchaseQty * X.IntakeSellingPrice) 
            + 
            (X.InventoryBalance * X1.RunningAVG )
            ) /X.NewBalance [RunningAVG]
    from AKTest X
    join Testcte X1 on X.ReceiptNo = X1.ReceiptNo +1
    and X.[Item No_]='2000045'
   )
SELECT *
FROM   Testcte;

对于上面的查询,结果是平均值是:

75.000000
75.000000
75.002070
sql-server tsql sql-server-2012 recursive-query
1个回答
1
投票

除非我遗漏了某些内容,否则您需要做的就是从cte中删除硬编码的项目编号(锚点部分中的and A.[Item No_]='2000045',以及递归部分中的and A.[Item No_]='2000045'),并且只需将项目编号的递归部分加入:

;WITH   Testcte
AS     (
SELECT A.*, (
                (A.PurchaseQty * A.IntakeSellingPrice) 
                    + 
                    (A.InventoryBalance *  isnull(A2.IntakeSellingPrice, A.IntakeSellingPrice))
                ) /A.NewBalance [RunningAVG]

    from AKTest A
    left join AKTest A2 on A.[Item No_] = A2.[Item No_] and A.ReceiptNo = A2.ReceiptNo +1
    where A.ReceiptNo = 1 -- anchor member
    -- and A.[Item No_]='2000045' -- removed this condition
UNION ALL

SELECT X.* , (
            (X.PurchaseQty * X.IntakeSellingPrice) 
            + 
            (X.InventoryBalance * X1.RunningAVG )
            ) /X.NewBalance [RunningAVG]
    from AKTest X
    join Testcte X1 on X.ReceiptNo = X1.ReceiptNo +1
    and X.[Item No_] = X1.[Item No_] -- this is instead of the next line (that's commeneted out)
    -- and X.[Item No_]='2000045' -- removed this as well
   )
© www.soinside.com 2019 - 2024. All rights reserved.