将Access计算字段转换为T-SQL

时间:2018-08-29 13:51:35

标签: sql sql-server tsql ms-access migrate

我正在尝试手动迁移实际上是一个表达式(访问中的计算字段)的访问查询。

有问题的访问表达式是:

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 < / p>

3 个答案:

答案 0 :(得分:3)

我会这样写:

     (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中不需要条件逻辑。

答案 1 :(得分:2)

快速重写以提高性能和移植性:

CASE 
  WHEN [Order Transactions Table].[OutstandingBalance] < [PartsStockForJobTotals].[EXPR1] 
    THEN [Order Transactions Table].[OutstandingBalance] - ISNULL([PartsStockForJobTotals].[EXPR1], 0)
  ELSE 0 
  END AS Balance2

切换到此处使用CASE语句,该语句类似于IIF(),但更便于移植(除了Access以外,在任何RDBMS中都可以使用),其中IIF()仅适用于SQL Server和Windows Server的较新版本。访问权限(不是Oracle,Postgres,DB2,MySQL,MariaDB等等等)。

将两个值相减并测试>0的数学运算也很昂贵。只需测试一下是否大于另一个即可。

最后,您的ELSE条件只能写为0而不是0 * [Part Assembly Link Table].[QTY],因为任何时候0都是0。

这在您的WHERE子句中也应该可以正常工作(尽管我不知道为什么您的WHERE首先会失败,所以可能还有更多原因)。

答案 2 :(得分:2)

我设法解决了这个问题!感谢 @Jnevill @Gordon Linoff ,它们简化了代码,但我的WHERE子句无法正常工作,因为我在表之间链接不正确。当多个实例添加到查询托盘时,Access将创建临时表。它将第二个实例附加 _1 (在我的情况下为 PART LIBARY HEADER_1

最初,我的加入没有指定此连接:

PART LIBARY HEADER ----> PART ASSEMBLY LINK TABLE ----> PART LIBARY HEADER_1

但是在重新执行联接之后,由 @Gordon Linoff 提供的where子句似乎可以解决问题。准确的结果将按照在Access中的状态返回。

感谢您的所有帮助!