无法创建SQL查询以更新订单项金额

时间:2012-02-14 22:53:33

标签: sql-server sql-server-2008 tsql

我将在免责声明中提出这个问题,即创建我称之为“复杂”的查询并不是我的强项。大多数时候,有一种更简单的方法来完成我想要完成的任务,所以如果下面的查询达不到标准,我道歉。

话虽如此,我有一张表来跟踪供应商发票和供应商发票项目(以及供应商发票类型和供应商发票项目类型)。我们的簿记员需要一份简单的报告:供应商|位置| Inv号码| Inv类型|项目类型| Inv日期|租赁费|补货费|运费|订单项成本|总计(行项目+费用)

大多数情况下,一个供应商发票是一行。但是,有一些例外情况,供应商发票可以有多种项目类型,从而创建两行。不是什么大不了,除了费用(租赁,重新库存,运输)附加到供应商发票表。所以,我首先创建了一个查询,检查具有多行的发票的临时表,取最后一行,并将费用归零。因此,只有一个订单项会收取费用。但是,我们的簿记员并不喜欢这样。相反,她希望这些费用在订单项中“分配”。

因此,如果供应商发票的运费为25美元,则有两个订单项,则每个订单项的费用为12.50美元。

使用查询后,我得到它将最后一行更新为调整后的数量,但第1行将具有原始数量。

我将在这里发布我的整个查询(再次 - 我很抱歉这可能不是最好看的查询;但是,建议随时欢迎)

DROP TABLE #tVendorInvoiceReport
DROP TABLE #tSummary

SELECT  v.Name AS Vendor ,
    vii.Location ,
    vi.VendorInvNumber ,
    vit.Descr AS InvoiceType ,
    vii.VendorInvoiceItemType ,
    CONVERT(VARCHAR(10), vi.VendorInvDate, 120) VendorInvDate ,
    vi.RentalFee ,
    vi.RestockFee ,
    vi.ShippingFee ,
    SUM(vii.TotalUnitCost) TotalItemCost ,
    CONVERT(MONEY, 0) TotalInvoice  ,
    RowID = IDENTITY( INT,1,1)
INTO    #tVendorInvoiceReport
FROM    dbo.vVendorInvoiceItems AS vii
    JOIN dbo.VendorInvoices AS vi ON vii.VendorInvID = vi.VendorInvID
    JOIN dbo.Vendors AS v ON vi.VendorID = v.VendorID
    JOIN dbo.VendorInvoiceTypes AS vit ON vi.VendorInvTypeID = vit.VendorInvTypeID
WHERE   vi.VendorInvDate >= '2012-01-01'
    AND vi.VendorInvDate <= '2012-01-31'
GROUP BY v.Name ,
    vii.Location ,
    vi.VendorInvNumber ,
    vit.Descr ,
    vii.VendorInvoiceItemType ,
    CONVERT(VARCHAR(10), vi.VendorInvDate, 120) ,
    vi.RentalFee ,
    vi.RestockFee ,
    vi.ShippingFee
ORDER BY v.Name ,
    vii.Location ,
    vi.VendorInvNumber ,
    vit.Descr ,
    vii.VendorInvoiceItemType ,
    CONVERT(VARCHAR(10), vi.VendorInvDate, 120)


SELECT  VendorInvNumber ,
    COUNT(RowID) TotalLines ,
    MAX(RowID) LastLine
INTO    #tSummary
FROM    #tVendorInvoiceReport
GROUP BY VendorInvNumber

WHILE ( SELECT  COUNT(LastLine)
    FROM    #tSummary AS ts
    WHERE   TotalLines > 1
  ) > 0 
BEGIN
    DECLARE @LastLine INT
    DECLARE @NumItems INT

    SET @LastLine = ( SELECT    MAX(LastLine)
                      FROM      #tSummary AS ts
                      WHERE     TotalLines > 1
                    )

    SET @NumItems = ( SELECT    COUNT(VendorInvNumber)
                      FROM      #tVendorInvoiceReport
                      WHERE     VendorInvNumber IN (
                                SELECT  VendorInvNumber
                                FROM    #tSummary
                                WHERE   LastLine = @LastLine )
                    ) 

    UPDATE  #tVendorInvoiceReport
    SET     RentalFee = ( RentalFee / @NumItems ) ,
            RestockFee = ( RestockFee / @NumItems ) ,
            ShippingFee = ( ShippingFee / @NumItems )
    WHERE   RowID = @LastLine

    DELETE  FROM #tSummary
    WHERE   LastLine = @LastLine

    --PRINT @NumItems
END

UPDATE  #tVendorInvoiceReport
SET     TotalInvoice = ( TotalItemCost + RentalFee + RestockFee + ShippingFee )

SELECT  Vendor ,
    Location ,
    VendorInvNumber ,
    InvoiceType ,
    VendorInvoiceItemType ,
    VendorInvDate ,
    RentalFee ,
    RestockFee ,
    ShippingFee ,
    TotalItemCost ,
    TotalInvoice
FROM    #tVendorInvoiceReport AS tvir

我真诚地感谢任何花时间阅读本文并试图指出我正确方向的人。

谢谢你, 安德鲁

PS - 我确实尝试从第一次更新中删除“WHERE RowID = @LastLine”,但这改变了第一行的运费,其中两项为“0.0868”而不是12.50($ 25/2)

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您正在寻找一种方法,可以将发票运费等分成一个或多个发票项目。

我创建了一些示例发票和发票项目表,如下所示并使用了 over(partition) clause分拆每件商品的运费。

-- sample tables
declare @Invoice table (InvoiceID int, customerID int, Date datetime, ShippingFee float)
declare @InvoiceItem table (InvoiceItemID int identity, InvoiceID int, ItemDesc varchar(50), Quantity float, ItemPrice float)

-- Example 1
insert @Invoice values(1, 800, getdate(), 20);
insert @InvoiceItem values(1, 'Widget', 1, 10.00)
insert @InvoiceItem values(1, 'Wing Nut', 5, 2.00)
insert @InvoiceItem values(1, 'Doodad', 8, 0.50)
insert @InvoiceItem values(1, 'Thingy', 3, 1.00)

-- Example 2
insert @Invoice values(2, 815, getdate(), 15);
insert @InvoiceItem values(2, 'Green Stuff', 10, 1.00)
insert @InvoiceItem values(2, 'Blue Stuff', 10, 1.60)

-- Example 3
insert @Invoice values(3, 789, getdate(), 15);
insert @InvoiceItem values(3, 'Widget', 10, 1.60)

-- query
select 
    n.InvoiceID,
    n.InvoiceItemID,
    n.ItemDesc,
    n.Quantity,
    n.ItemPrice,
    ExtendedPrice = n.Quantity *    n.ItemPrice,
    Shipping = i.ShippingFee / count(n.InvoiceItemID) over(partition by n.InvoiceID)
from @InvoiceItem n
    join @Invoice i on i.InvoiceID = n.InvoiceID

输出:

    InvoiceID   InvoiceItemID   ItemDesc    Quantity    ItemPrice   ExtendedPrice   Shipping
    1           1               Widget      1           10          10                  5
    1           2               Wing Nut    5           2           10                  5
    1           3               Doodad      8           0.5         4                   5
    1           4               Thingy      3           1           3                   5

    2           5               Green Stuff 10          1           10                  7.5
    2           6               Blue Stuff  10          1.6         16                  7.5

    3           7               Widget      10          1.6         16                  15