受约束的几年的每日总和

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

下面代码中所有列的结果均准确,但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
date ms-access subquery constraints aggregate-functions
1个回答
0
投票

您正在使用“相关子查询”,应该在子查询中引用外部查询,但是您不会这样做。您需要在该子查询中有一个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
© www.soinside.com 2019 - 2024. All rights reserved.