下面代码中所有列的结果均准确,但COGS列除外。由于需要约束,因此子查询用于COGS列。 COGS列中每个日期的结果相同,并且值是整个年份范围内每天总和的总和。问题出现在COGS子查询中,而不是将总和限制为一天。
SELECT
Format(s.sale_date, "mm/dd/yyyy") AS [Month / Day / Year],
ROUND(SUM(Nz(s.SELLING_PRICE, 0) * Nz(s.quantity, 0)), 2) AS [Gross Sales],
(SELECT
ROUND(Nz(SUM((Nz(i.VENDOR_ACTUAL_PRICE, 0)) * s.quantity), 0), 2)
FROM SALES_RECEIPT s
INNER JOIN INVENTORY i
ON i.INVENTORY_ID = S.INVENTORY_ID
WHERE YEAR(s.sale_date) BETWEEN 2000 AND 2100
AND i.consignment IS NULL
OR i.consignment = 'No')
AS COGS,
ROUND(SUM(Nz(s.SELLING_PRICE, 0) * Nz(s.quantity, 0)) - SUM(Nz(i.VENDOR_ACTUAL_PRICE * s.quantity, 0)), 2) AS [Sales Margin],
ROUND([Sales Margin] / [Gross Sales], 2) AS [Profit Margin]
FROM inventory i
INNER JOIN sales_receipt s
ON i.inventory_id = s.inventory_id
WHERE YEAR(s.sale_date) BETWEEN 2000 AND 2100
GROUP BY format(s.sale_date, "mm/dd/yyyy"),
s.sale_date
ORDER BY s.sale_date
您正在使用“相关子查询”,应该在子查询中引用外部查询,但是您不会这样做。您需要在该子查询中有一个where谓词,该谓词引用我已使用AND s_1.inventory_id = i.inventory_id
引入的“外部”表别名i。还请注意我如何更改在该子查询中形成的别名-这在这里很重要,否则您将无法识别从“内部”到该子查询的“外部”表。
SELECT
format(s.sale_date, "mm/dd/yyyy")
, s.sale_date
, ROUND(SUM(Nz(s.SELLING_PRICE, 0) * Nz(s.quantity, 0)), 2) AS [Gross Sales]
, (
SELECT ROUND(Nz(SUM((Nz(i_1.VENDOR_ACTUAL_PRICE, 0)) * s_1.quantity), 0), 2)
FROM SALES_RECEIPT s_1
INNER JOIN INVENTORY i_1
ON i_1.INVENTORY_ID = S_1.INVENTORY_ID
WHERE YEAR(s_1.sale_date) BETWEEN 2000 AND 2100
AND (
i_1.consignment IS NULL
OR i_1.consignment = 'No'
)
AND s_1.inventory_id = i.inventory_id
) AS COGS
, ROUND(SUM(Nz(s.SELLING_PRICE, 0) * Nz(s.quantity, 0)) - SUM(Nz(i.VENDOR_ACTUAL_PRICE * s.quantity, 0)), 2) AS [Sales Margin]
, ROUND([Sales Margin] / [Gross Sales], 2) AS [Profit Margin]
FROM inventory i
INNER JOIN sales_receipt s
ON i.inventory_id = s.inventory_id
WHERE YEAR(s.sale_date) BETWEEN 2000
AND 2100
GROUP BY
format(s.sale_date, "mm/dd/yyyy")
, s.sale_date
ORDER BY s.sale_date
尽管也要注意,关联子查询通常很慢,而且使用“派生表”方法可能会好得多。就是说,在from子句中执行子查询,然后将表连接到该子查询结果。例如
SELECT
format(s.sale_date, "mm/dd/yyyy")
, s.sale_date
, ROUND(SUM(Nz(s.SELLING_PRICE, 0) * Nz(s.quantity, 0)), 2) AS [Gross Sales]
, COGS.COGS
, ROUND(SUM(Nz(s.SELLING_PRICE, 0) * Nz(s.quantity, 0)) - SUM(Nz(i.VENDOR_ACTUAL_PRICE * s.quantity, 0)), 2) AS [Sales Margin]
, ROUND([Sales Margin] / [Gross Sales], 2) AS [Profit Margin]
FROM inventory i
INNER JOIN sales_receipt s
ON i.inventory_id = s.inventory_id
lEFT JOIN (
SELECT
s_1.sale_date
, s_1.inventory_id
, ROUND(Nz(SUM((Nz(i_1.VENDOR_ACTUAL_PRICE, 0)) * s_1.quantity), 0), 2) COGS
FROM SALES_RECEIPT s_1
INNER JOIN INVENTORY i_1
ON i_1.INVENTORY_ID = S_1.INVENTORY_ID
WHERE YEAR(s_1.sale_date) BETWEEN 2000 AND 2100
AND (
i_1.consignment IS NULL
OR i_1.consignment = 'No'
)
AND s_1.inventory_id = i.inventory_id
GROUP BY
s_1.sale_date
, s_1.inventory_id
) COGS i.inventory_id = COGS.inventory_id and s.sale_date = COGS.sale_date
WHERE YEAR(s.sale_date) BETWEEN 2000 AND 2100
GROUP BY
format(s.sale_date, "mm/dd/yyyy")
, s.sale_date
ORDER BY s.sale_date