我正在尝试手动迁移访问查询,这实际上是一个表达式(访问中的计算字段)。
有问题的访问表达式是:
Balance2: (IIf(([OutstandingBalance]-nz([PartsStockForJobTotals]!
[Expr1]))>0,([OutstandingBalance]-nz([PartsStockForJobTotals]![Expr1])),0))*
[Part Assembly Link Table]![Qty]
到目前为止,我已设法编写SQL代码:
SELECT
IIF([Order Transactions Table].[OutstandingBalance] -
ISNULL([PartsStockForJobTotals].[EXPR1], 0) >0,
[Order Transactions Table].[OutstandingBalance] -
ISNULL([PartsStockForJobTotals].[EXPR1], 0), 0 *
[Part Assembly Link Table].[QTY]) AS Balance2,
FROM ((([PART LIBARY HEADER]
INNER JOIN [Part Assembly Link Table]
ON [PART LIBARY HEADER].PartID = [Part Assembly Link Table].PartIDParent)
INNER JOIN [PART LIBARY HEADER] AS [PART LIBARY HEADER_1]
ON [Part Assembly Link Table].PartIDChild = [PART LIBARY HEADER].PartID)
INNER JOIN [Order Transactions Table]
ON [PART LIBARY HEADER].[Part Number] = [Order Transactions Table].[Part
Number])
LEFT JOIN PartsStockForJobTotals
ON [Order Transactions Table].[Item Referance] = PartsStockForJobTotals.
[Item Referance]
现在一直到此为止都会返回记录。但是我试图仅过滤'Balance2'大于0的记录。
这是我使用的WHERE子句但它不检索任何行:
WHERE
IIF([Order Transactions Table].[OutstandingBalance] -
ISNULL([PartsStockForJobTotals].[EXPR1], 0) >0,
[Order Transactions Table].[OutstandingBalance] -
ISNULL([PartsStockForJobTotals].[EXPR1], 0), 0 *
[Part Assembly Link Table].[QTY]) > 0;
显然,不允许在WHERE子句中使用别名,所以我只是将'Balance2'复制并粘贴到where语句中并附加了> 0
我会这样写:
(CASE WHEN ott.[OutstandingBalance] < COALESCE(psfjt.[EXPR1], 0)
THEN ott.[OutstandingBalance] - COALESCE(psfjt.[EXPR1], 0)
ELSE 0
END) * palt.[Qty] AS Balance2
. . .
FROM . . .
[Order Transactions Table] ott . . .
[PartsStockForJobTotals] psfjt . . .
[Part Assembly Link Table] palt
表别名使查询更易于编写和读取。
那么WHERE
将是:
WHERE (ott.OutstandingBalance - COALESCE(psfjt.EXPR1, 0)) * palt.qty > 0
我认为在WHERE
中不需要条件逻辑。
快速重写您的重写,以提高性能和可移植性:
CASE
WHEN [Order Transactions Table].[OutstandingBalance] < [PartsStockForJobTotals].[EXPR1]
THEN [Order Transactions Table].[OutstandingBalance] - ISNULL([PartsStockForJobTotals].[EXPR1], 0)
ELSE 0
END AS Balance2
切换到这里使用类似于IIF()
的CASE语句,但更易于移植(可在除Access之外的任何RDBMS中工作),其中IIF()
仅适用于较新版本的SQL Server和Access(不是Oracle,Postgres,DB2,MySQL, MariaDB等等等)。
另外,减去这两个值并测试>0
的数学成本很高。只是测试一个是否大于另一个。
最后你的ELSE
条件可以写成0
而不是0 *
[Part Assembly Link Table].[QTY]
,因为任何时候0都是0。
这应该在你的WHERE子句中也可以正常工作(虽然我不知道为什么你的WHERE首先失败了,所以可能还有更多这个)。
我设法解决了这个问题!感谢@Jnevill和@Gordon Linoff的代码简化,但是我的WHERE子句无效,因为表之间的链接不正确。当多个实例添加到查询托盘时,Access会创建临时表。它将第二个实例附加到_1,在我的例子中是PART LIBARY HEADER_1
最初我的Joins没有指定这个连接:
PART LIBARY HEADER ----> PART ASSEMBLY LINK TABLE ----> PART LIBARY HEADER_1
但在重新加入@Gordon Linoff提供的where子句之后似乎可以解决问题。确切的结果将在Access中返回。
感谢你的帮助!