我创建了一个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 = 0
或CY.CurSales = 0
。如果任一结果为空/空/零,我不会从我的表达式中得到结果。我在这里寻找解决方案没有运气。任何人都可以指出我错过了什么?我觉得它必须非常简单。
由于您似乎在MS Access中运行完全外连接并且需要返回非NULL Sales列,因此请考虑在NZ()
之前使用SUM()
包装每个Amount,这将确保返回至少为零:
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);
问题是,对于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
语句,但仍会影响字段类型。