给出如下SQL查询
DECLARE @StartDate NVARCHAR(MAX) = '20170815'
DECLARE @FinishDate NVARCHAR(MAX) = '20170815'
SELECT
cid.ItemCode,
cid.InvoiceCode,
SUM(ROUND(cid.ExtPrice, 2)) AS 'TotalExGST'
FROM CustomerInvoice ci
JOIN CustomerInvoiceDetail cid
ON ci.InvoiceCode = cid.InvoiceCode
WHERE ci.IsVoided = 0
AND dbo.ConvertDate_C(ci.InvoiceDate)
BETWEEN @StartDate AND @FinishDate
GROUP BY ci.invoicecode, ItemCode
UNION ALL
SELECT
'Freight',
ci.InvoiceCode,
ci.Freight
FROM CustomerInvoice ci
WHERE ci.IsVoided = 0
AND dbo.ConvertDate_C(ci.InvoiceDate) BETWEEN @StartDate AND @FinishDate
GROUP BY ci.invoicecode, ci.Freight
返回这样的数据(为简单起见,只显示一张发票)
╔═════════════╦══════════════╦══════════════╗
║ Item Code ║ Invoice Code ║ Total Ex GST ║
╠═════════════╬══════════════╬══════════════╣
║ Freight ║ INV-255390 ║ 20.000000 ║
╠═════════════╬══════════════╬══════════════╣
║ ITEM-002605 ║ INV-255390 ║ 47.120000 ║
╠═════════════╬══════════════╬══════════════╣
║ ITEM-002679 ║ INV-255390 ║ 11.260000 ║
╠═════════════╬══════════════╬══════════════╣
║ ITEM-002687 ║ INV-255390 ║ 10.860000 ║
╠═════════════╬══════════════╬══════════════╣
║ ITEM-028905 ║ INV-255390 ║ 58.480000 ║
╚═════════════╩══════════════╩══════════════╝
如何获取每张发票上的订单项总数,并将运费金额按该总额平均分摊,然后将其与项目价格相加?
项目和价格位于CustomerInvoiceDetail
表格上,而运费则位于CustomerInvoice
表格上,这些可以在InvoiceCode
列上加入。
预期输出看起来像,并按如下方式计算:
Number of items on invoice = 4
Freight cost = 20
Split Freight Cost = 20 / 4 = 5
Then add 5 to all the items, and thus remove freight row from the query.
╔═════════════╦═════════════╦════════════╗
║ ItemCode ║ InvoiceCode ║ TotalExGST ║
╠═════════════╬═════════════╬════════════╣
║ ITEM-002605 ║ INV-255390 ║ 52.12 ║
╠═════════════╬═════════════╬════════════╣
║ ITEM-002679 ║ INV-255390 ║ 16.26 ║
╠═════════════╬═════════════╬════════════╣
║ ITEM-002687 ║ INV-255390 ║ 15.86 ║
╠═════════════╬═════════════╬════════════╣
║ ITEM-028905 ║ INV-255390 ║ 63.48 ║
╚═════════════╩═════════════╩════════════╝
答案 0 :(得分:1)
我会将您的查询包装到CTE中以使其更具可读性。
CTE_InvoiceFreight
每张发票一行包含运费金额。
CTE_InvoiceItems
提供发票项目。
我与LEFT JOIN
加入,以防有没有运费的发票。
COUNT(*) OVER (...)
会计算每张发票中的项目数,而不会额外GROUP BY
。
取消评论最终SELECT
中的列,以查看中间结果。
DECLARE @StartDate NVARCHAR(MAX) = '20170815'
DECLARE @FinishDate NVARCHAR(MAX) = '20170815'
WITH
CTE_InvoiceFreight
AS
(
-- this query returns at most one row per InvoiceCode
SELECT
ci.InvoiceCode
,SUM(ci.Freight) AS TotalInvoiceFreight
FROM
CustomerInvoice AS ci
WHERE
ci.IsVoided = 0
AND dbo.ConvertDate_C(ci.InvoiceDate) BETWEEN @StartDate AND @FinishDate
GROUP BY
ci.InvoiceCode
)
,CTE_InvoiceItems
AS
(
SELECT
cid.ItemCode
,cid.InvoiceCode
,SUM(ROUND(cid.ExtPrice, 2)) AS TotalExGST
FROM
CustomerInvoice AS ci
INNER JOIN CustomerInvoiceDetail AS cid ON ci.InvoiceCode = cid.InvoiceCode
WHERE
ci.IsVoided = 0
AND dbo.ConvertDate_C(ci.InvoiceDate) BETWEEN @StartDate AND @FinishDate
GROUP BY
cid.ItemCode
,cid.InvoiceCode
)
SELECT
CTE_InvoiceItems.ItemCode
,CTE_InvoiceItems.InvoiceCode
-- ,CTE_InvoiceItems.TotalExGST
-- ,COUNT(*) OVER (PARTITION BY CTE_InvoiceItems.InvoiceCode) AS InvoiceItemsCount
-- ,ISNULL(CTE_InvoiceFreight.TotalInvoiceFreight, 0) AS TotalInvoiceFreight
,CTE_InvoiceItems.TotalExGST
+ ROUND(
ISNULL(CTE_InvoiceFreight.TotalInvoiceFreight, 0) /
COUNT(*) OVER (PARTITION BY CTE_InvoiceItems.InvoiceCode)
, 2) AS TotalWithFreightExGST
FROM
CTE_InvoiceItems
LEFT JOIN CTE_InvoiceFreight
ON CTE_InvoiceFreight.InvoiceCode = CTE_InvoiceItems.InvoiceCode
ORDER BY
CTE_InvoiceItems.InvoiceCode
,CTE_InvoiceItems.ItemCode
;
答案 1 :(得分:0)
结束使用每张发票上的发票代码和项目数进行子查询。
然后我用它来计算拆分运费金额并将其添加到每个项目中。
SELECT
ci.InvoiceDate,
ci.InvoiceCode,
cid.ItemCode,
SUM(ROUND(cid.ExtPrice, 2)) + SUM(ROUND((ci.Freight / ItemSum.NoOfItems),2)) + SUM(ROUND((ci.Other / ItemSum.NoOfItems),2)) AS 'TotalExGst',
FROM CustomerInvoiceDetail cid
JOIN (
SELECT ci.InvoiceCode, COUNT(*) AS 'NoOfItems'
FROM CustomerInvoiceDetail cid
JOIN CustomerInvoice ci
ON cid.InvoiceCode = ci.InvoiceCode
GROUP BY ci.InvoiceCode
) ItemSum
ON cid.InvoiceCode = ItemSum.InvoiceCode
JOIN CustomerInvoice ci ON cid.InvoiceCode = ci.InvoiceCode
WHERE ci.IsVoided = 0
AND dbo.ConvertDate_C(ci.InvoiceDate)
BETWEEN @StartDate AND @FinishDate
GROUP BY ci.InvoiceCode, cid.ItemCode, ci.InvoiceDate