【问题标题】:How do I create a new total row for each invoice that shows the sum of each unique invoice?如何为每张发票创建一个新的总行以显示每张唯一发票的总和?
【发布时间】:2020-06-09 17:33:12
【问题描述】:

如何为每张发票创建一个新的总行以显示每张唯一发票的总和?我相信有一个使用分区的窗口函数。在下图中,每张发票应具有相同的“TAX AMT”和“FRGHT AMT”(如果有)(在这种情况下,它恰好是 0.00)。我正在尝试在每个“INVOICE”之后创建一个新行,将“TAX AMT”、“FRGHT AMT”和“EXT PRICE”相加,并将其放在“TOT MAT”中。

第二张图片显示了我正在尝试制作的内容。

SELECT ORDERNUM AS INVOICE
    ,PRODUCTLIST.ID AS ITEM
    ,PRODUCTLIST.DESC1 AS [DESC]
    ,INVDATE AS [INV DATE]
    ,format(USELL, 'N') AS PRICE
    ,QTYSOLD - QTYRETN AS QTY
    ,format(DOLSOLD - DOLRETN, 'N') AS [EXT PRICE]
    ,format(TAX_AMOUNT, 'N') AS [TAX AMT]
    ,format(FREIGHT, 'N') AS [FRGHT AMT]
    ,0.00 AS [HDL]
    ,0.00 AS [TOT MAT]
    ,PO_NUMBER AS [PO NBR]
FROM History
INNER JOIN PRODUCTLIST ON PARTNUM = UID
WHERE BILLTOID = '28736'
    AND INVDATE >= '2/21/2020' --and ordernum = 'S2149853.001'
ORDER BY INVDATE
    ,ORDERNUM

【问题讨论】:

  • 这些微小的图像很难阅读,也无法操作。您应该以文本形式提供所有这些信息。数据库标签以及相关表中的示例数据也会有所帮助。
  • 供您参考,this 是一个完整构造的问题的样子。有关用于改进问题的提示和工具,这里有一篇很好的参考文章。 How to post a SQL question on a public forum

标签: sql database group-by window-functions


【解决方案1】:

编辑 01:将最终查询更新为不求和 TAXAMT 和 FRGHTAMT

你走在正确的轨道上。我们将使用窗口聚合来按发票获取总数,并使用联合将其添加为新行。

创建样本数据:

DECLARE @tbl TABLE (
    INVOICE INT,
    EXTPRICE NUMERIC(32,2),
    TAXAMT NUMERIC(32,2),
    FRGHTAMT NUMERIC(32,2)
)

INSERT INTO @tbl
VALUES
(1,172.5,0,0)
,(1,105.26,0,0)
,(1,15.76,0,0)
,(1,129.64,0,0)
,(1,42.1,0,0)
,(1,284.22,0,0)
,(1,23.14,0,0)
,(1,90.52,0,0)
,(1,168.4,0,0)
,(2,11.46,0,0)
,(2,13.75,0,0)
,(2,17.95,0,0)
,(2,13.46,0,0)
,(2,13.46,0,0)

接下来我们需要计算发票的总 EXTPRICE + 发票的总 TAXAMT + 发票的总 FRGHTAMT。

SELECT
    *,
    SUM(EXTPRICE) OVER (PARTITION BY INVOICE)   --Total EXTPRICE by invoice
    + SUM(TAXAMT) OVER (PARTITION BY INVOICE)   --Total TAXAMT by invoice
    + SUM(FRGHTAMT) OVER (PARTITION BY INVOICE) --TOTAL FRGHTAMT by invoice
        AS InvoiceTotal
FROM @tbl

最后,要使这成为新行而不是附加列,我们需要查询表两次并将它们合并。因为联合需要相同数量的列和数据类型,所以我将行项目的发票总计保留为 NULL,并将单个价格保留为总计为 NULL。如果需要,您还可以按行项目计算总计。

编辑 01:InvoiceTotal 更新为仅计算 TAXAMT 和 FRGHTAMT 一次,而不是在窗口函数中对其求和。

SELECT
    INVOICE,
    'LineItem' AS RecordType,
    EXTPRICE,
    TAXAMT,
    FRGHTAMT,
    NULL AS InvoiceTotal
FROM @tbl
UNION ALL
SELECT DISTINCT
    INVOICE,
    'Total',
    NULL,
    NULL,
    NULL,
    SUM(EXTPRICE) OVER (PARTITION BY INVOICE)   --Total EXTPRICE by invoice
    + TAXAMT
    + FRGHTAMT
        AS InvoiceTotal
FROM @tbl
ORDER BY INVOICE,RecordType

【讨论】:

  • 谢谢你。我用不同的'TAXAMT'玩过它。例如3.00。此金额将是发票的 3.00,但只能在“发票总额”中添加一次。知道怎么做吗?
  • 好的,我修改了最后两个查询,只添加了“TAXAMT”和“FRGHTAMT”。似乎有效。
  • 现在我正在尝试进一步修改并在“总计”行中仅显示一次“TAXAMT”和“FRGHTAMT”,并分别在“TAXAMT”和“FRGHTAMT”每列中显示 0.00。另一个联合语句或选择语句会完成此操作吗?非常感谢
  • 要计算一次而不是对每个行项目(在本例中为 TAXAMT)进行汇总,将 SUM(TAXAMT) OVER (PARTITION BY INVOICE) 替换为 MAX(TAXAMT) OVER (PARTITION BY INVOICE)。由于它们都是相同的,您可以只使用没有窗口函数的 TAXAMT。由于第二个查询是不同的,如果它们都相同,它将返回 1 条记录。如果由于任何原因它们不同,MAX 将返回最高值进行计算。您也可以进行 AVG,但同样,如果它们都相同,则不需要任何功能。
猜你喜欢
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多