将 Access 计算字段转换为 T-SQL
Converting Access calculated field to T-SQL
我正在尝试手动迁移实际上是表达式的访问查询(访问中的计算字段。
有问题的访问表达式是:
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]
现在 returns 记录之前的所有内容。但是,我试图仅过滤“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 [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 服务器和访问(不是 Oracle、Postgres、DB2、MySQL、MariaDB 等等)。
减去两个值并测试 >0
的数学运算也很昂贵。只是测试一个是否大于另一个。
最后,您的 ELSE
条件可以写成 0
而不是 0 *
[Part Assembly Link Table].[QTY]
,因为任何时间 0 都是 0。
这在你的 WHERE 子句中应该也能正常工作(虽然我不知道为什么你的 WHERE 首先失败,所以可能还有更多)。
我会这样写:
(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
Table 别名使查询更易于编写和阅读。
那么 WHERE
将是:
WHERE (ott.OutstandingBalance - COALESCE(psfjt.EXPR1, 0)) * palt.qty > 0
我认为 WHERE
中不需要条件逻辑。
我已经设法解决了这个问题!感谢 @Jnevill 和 @Gordon Linoff 简化了代码,但我的 WHERE 子句不起作用,因为我的 link 不正确桌子。当多个实例添加到查询托盘时,Access 会创建临时表。它将第二个实例附加 _1,在我的例子中是 PART LIBARY HEADER_1
最初我的连接没有指定这个连接:
PART LIBARY HEADER ----> PART ASSEMBLY LINK TABLE ----> PART LIBARY HEADER_1
但是在重新执行连接后,@Gordon Linoff 提供的 where 子句似乎可以解决问题。将返回准确的结果,因为它在 Access 中。
感谢您的帮助!
我正在尝试手动迁移实际上是表达式的访问查询(访问中的计算字段。
有问题的访问表达式是:
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]
现在 returns 记录之前的所有内容。但是,我试图仅过滤“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 [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 服务器和访问(不是 Oracle、Postgres、DB2、MySQL、MariaDB 等等)。
减去两个值并测试 >0
的数学运算也很昂贵。只是测试一个是否大于另一个。
最后,您的 ELSE
条件可以写成 0
而不是 0 *
[Part Assembly Link Table].[QTY]
,因为任何时间 0 都是 0。
这在你的 WHERE 子句中应该也能正常工作(虽然我不知道为什么你的 WHERE 首先失败,所以可能还有更多)。
我会这样写:
(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
Table 别名使查询更易于编写和阅读。
那么 WHERE
将是:
WHERE (ott.OutstandingBalance - COALESCE(psfjt.EXPR1, 0)) * palt.qty > 0
我认为 WHERE
中不需要条件逻辑。
我已经设法解决了这个问题!感谢 @Jnevill 和 @Gordon Linoff 简化了代码,但我的 WHERE 子句不起作用,因为我的 link 不正确桌子。当多个实例添加到查询托盘时,Access 会创建临时表。它将第二个实例附加 _1,在我的例子中是 PART LIBARY HEADER_1
最初我的连接没有指定这个连接:
PART LIBARY HEADER ----> PART ASSEMBLY LINK TABLE ----> PART LIBARY HEADER_1
但是在重新执行连接后,@Gordon Linoff 提供的 where 子句似乎可以解决问题。将返回准确的结果,因为它在 Access 中。
感谢您的帮助!