联合查询中的计算表达式(MS Access)

时间:2018-02-28 20:48:41

标签: sql ms-access union

我创建了一个UNION ALL来加入销售数据客户的“同比”总计。当前月份和年份从用户获得并传递给查询,我获得客户列,今年销售额(CY)和去年销售额(PY)。一切正常。

现在我想添加一个计算出的差异列。这是我的代码,显示SELECT语句中的表达式:

SELECT
   IIF(CY.Cust <> "", CY.Cust, PY.Cust) AS Cust,
   CY.CurSales AS CurSales,
   PY.PriSales AS PriSales,
   PY.PriSales - CY.CurSales AS Diff 
FROM
   (SELECT
         [Unique] AS Cust,
         SUM(Amount) AS CurSales 
      FROM
         Sales_Data 
      WHERE
         (Month <= Forms!SalesInput!MonthNum AND 
          [Sales_Data]![Year] = Forms!SalesInput!Year)
      GROUP BY
         [Unique]
   ) AS CY 

   LEFT OUTER JOIN
      (SELECT
            [Unique] AS Cust,
            SUM(Amount) AS PriSales 
         FROM
            Sales_Data 
         WHERE
            (Month <= Forms!SalesInput!MonthNum AND 
             [Sales_Data]![Year] = Forms!SalesInput!Year-1)
         GROUP BY
            [Unique]
      ) AS PY 
   ON (CY.Cust = PY.Cust) 

UNION ALL

SELECT
    IIF(CY.Cust <> "", CY.Cust, PY.Cust) AS Cust,
    CY.CurSales AS CurSales,
    PY.PriSales AS PriSales,
    PY.PriSales - CY.CurSales AS Diff 
FROM
   (SELECT
         [Unique] AS Cust,
         SUM(Amount) AS CurSales 
    FROM
        Sales_Data 
    WHERE
        (Month <= Forms!SalesInput!MonthNum AND 
         [Sales_Data]![Year] = Forms!SalesInput!Year)
     GROUP BY
        [Unique]
    ) AS CY 

    RIGHT OUTER JOIN
      (SELECT
           [Unique] AS Cust,
           SUM(Amount) AS PriSales 
       FROM
           Sales_Data 
       WHERE
           (Month <= Forms!SalesInput!MonthNum AND 
           [Sales_Data]![Year] = Forms!SalesInput!Year-1)
       GROUP BY
           [Unique]
      ) AS PY 
    ON (CY.Cust = PY.Cust) 

   WHERE
      (CY.Cust IS NULL AND PY.Cust IS NOT NULL);

除非PY.PriSales = 0CY.CurSales = 0,否则此方法有效。如果任一结果为空/空/零,我不会从我的表达式中得到结果。我在这里寻找解决方案没有运气。任何人都可以指出我错过了什么?我觉得它必须非常简单。

2 个答案:

答案 0 :(得分:0)

问题是,对于UNION个查询,字段类型由顶部查询确定。如果只返回Null,则会得到错误的字段类型。

您可以包含一个永远不会返回的标题行来设置标签和字段类型。

SELECT "String field" As Cust, CDbl(1.1) As CurSales, CDbl(1.1) As PriSales, 1.1 As Diff
FROM MSysObjects
WHERE FALSE
UNION ALL
... your unadjusted union query

请注意,我假设这些销售的字段类型属于Double类型。如果不正确,您可以在标题中使用替代演员。

Allen Browne写了另一个简单的技巧来确保字段类型here。它使用IIF语句,该语句始终返回一个选项,但仍会影响字段类型。

答案 1 :(得分:0)

由于您似乎在MS Access中运行完全外部联接并且需要返回非NULL Sales 列,因此请考虑使用NZ()包装每个 Amount SUM()之前,它将确保至少返回零:

SUM(NZ(Amount)) AS ...

您甚至可以在顶级

这样做
NZ(PY.PriSales) - NZ(CY.CurSales) AS Diff 

顺便说一下,考虑将聚合查询保存为存储的查询(即视图),并在更大的联合查询中引用它们,以获得更紧凑,可读的SQL:

SELECT
   IIF(CY.Cust <> '', CY.Cust, PY.Cust) AS Cust,
   CY.CurSales AS CurSales,
   PY.PriSales AS PriSales,
   NZ(PY.PriSales) - NZ(CY.CurSales) AS Diff 
FROM qryCYAgg AS CY 
LEFT JOIN qryPYAgg AS PY ON (CY.Cust = PY.Cust) 

UNION ALL

SELECT
    IIF(CY.Cust <> '', CY.Cust, PY.Cust) AS Cust,
    CY.CurSales AS CurSales,
    PY.PriSales AS PriSales,
    NZ(PY.PriSales) - NZ(CY.CurSales) AS Diff 
FROM qryCYAgg AS CY 
RIGHT JOIN qryPYAgg AS PY ON (CY.Cust = PY.Cust) 

WHERE (CY.Cust IS NULL AND PY.Cust IS NOT NULL);