简体   繁体   中英

Calculated expression in Union Query (MS Access)

I created a UNION ALL to join "year-over-year" totals by customer of sales data. The current month and year are obtained from the user and passed to the query and I get columns of customers, this year sales (CY) and last year sales (PY). It all works.

Now I want to add a calculated difference column. Here is my code showing the expression in the SELECT statement(s):

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);

This works unless either PY.PriSales = 0 OR CY.CurSales = 0 . If either result is blank/empty/zero I do not get a result from my expression. I've looked for the solution here with no luck. Can anyone point out what I'm missing? I feel like it's got to be pretty simple.

The problem is that, for UNION queries, the field type is determined by the top query. If that only returns Null , you get the wrong field type.

You can include a header row that never gets returned to set labels and field types.

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

Note that I'm assuming the field type of those sales are of the type Double . You can use an alternate cast in the header if that's not true.

Allen Browne has written an alternative simple trick to ensure the field type here . It uses an IIF statement that always returns one option, but still influences the field type.

Since you seem to be running the full outer join in MS Access and need to return non-NULL Sales columns, consider wrapping every Amount with NZ() before SUM() which will ensure at least zero is returned:

SUM(NZ(Amount)) AS ...

You may even be able to do so at top level

NZ(PY.PriSales) - NZ(CY.CurSales) AS Diff 

By the way, consider saving your aggregate queries as stored queries (ie, views) and reference them in larger union query for more compact, readable 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM