我创建了一个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
,否则此方法有效。如果任一结果为空/空/零,我不会从我的表达式中得到结果。我在这里寻找解决方案没有运气。任何人都可以指出我错过了什么?我觉得它必须非常简单。
答案 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);