【问题标题】:Access query IIF statement to SQL Server query访问查询 IIF 语句到 SQL Server 查询
【发布时间】:2020-02-18 18:56:24
【问题描述】:

问题:我正在尝试让下面的代码在 SQL Server 中工作。

我最初在 MS Access 查询中编写了代码,但现在我需要在 SQL Server 中使用它。我遇到的问题是 IIF 语句在 SQL Server 中不起作用。

我曾尝试使用Case 语句,但它最终使我的 SQL Server 陷入困境并且从未加载任何数据。关于如何将IIF 语句转换为在 SQL Server 中使用有什么建议吗?对于任何反馈,我们都表示感谢。谢谢!

用 MS Access 查询编写的代码:

SELECT 
    Customer.CustomerID, 
    IIf([ExpenseCode].[SysCode] >= '1747', [Amount], 0) AS Trains
FROM   
    Customer 
LEFT JOIN 
    (Expense 
LEFT JOIN 
    ExpenseCode ON Expense.SysCode = ExpenseCode.SysCode) ON Customer.CustomerID = Expense.EntityID;

在 SQL Server 中尝试的解决方案:

SELECT DISTINCT
    r.CustomerID,
    CASE
        WHEN t.SysCode = '1747'
           THEN e.Amount
        ELSE NULL
    END AS Trains
FROM
    ExpenseCode AS t, Expense AS e, Customer AS r

【问题讨论】:

  • IIF() 在 SQL Server 中受支持。
  • 但是IIF does work in SQL Server;它是在 SQL Server 2012 中引入的。如果您使用的版本早于该版本,则 CASE 等效项将是 CASE WHEN condition THEN truebranch ELSE falsebranch END - 您已将 >= 转换为 =0 转换为 NULL ,这似乎没有根据。
  • 如果您使用的 SQL Server 版本比 2012 年旧,那么您可能应该考虑升级路径。现在完全不支持 2012 年之前的任何版本。
  • 您实际收到了什么错误?您对 CASE 的实施看起来已经像是未来的建议。你所说的“陷入困境”是什么意思 - 这是否意味着查询从未完成?还是抛出错误?甚至是未知问题。另一个问题,您将 LEFT JOIN 变成了 CROSS JOIN,而 JOIN 中没有使用任何键 - 所以可能是性能错误?
  • Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 ANSI 中的 proper ANSI JOIN 语法-92 SQL 标准(25 多年前),不鼓励使用。您已经在 MS Access 中拥有正确的 JOINs - 不要为新的 SQL Server 代码降级FROM 中旧的“逗号分隔表”方法代码!

标签: sql sql-server ms-access iif


【解决方案1】:

自 2012 版起,SQL Server 支持IIF()。您需要在 MS Access 查询中更改的是联接的语法。

试试:

SELECT 
    c.CustomerID, 
    IIf(ec.SysCode >= 1747, Amount, 0) AS Trains
FROM   
    Customer c
    LEFT JOIN Expense e ON c.CustomerID = e.EntityID
    LEFT JOIN ExpenseCode ec ON e.SysCode = ec.SysCode;

我还为您的查询添加了表别名,因为它们使其更具可读性(请在列Amount 中添加相关前缀)。最后,我认为SysCode是一个数字,所以我去掉了值周围的引号进行比较(它确实是一个字符串,你可以把引号放回去)。

如果您运行的是 SQL Server CASE sytanx:

SELECT 
    c.CustomerID, 
    CASE WHEN ec.SysCode >= 1747 THEN Amount ELSE 0 END AS Trains
FROM   
    Customer c
    LEFT JOIN Expense e ON c.CustomerID = e.EntityID
    LEFT JOIN ExpenseCode ec ON e.SysCode = ec.SysCode;

【讨论】:

  • 我不确定你是否提到了这一点,但你似乎修改了它。他在SQL中的JOIN其实是一个CROSS JOIN,JOIN上没有逻辑,是3个表中的all to all
  • @Cato:OP 正在寻求将他们的查询从 MS Access 迁移到 SQL Server。显然他们使用隐式交叉连接的尝试不是正确的方法......
  • 我认为是真的,我只是向他指出,我认为这是他遇到的实际问题。
  • 您好 GMB,感谢您的反馈。我正在使用 SQL Server 2017,但可能我研究错误。我不断收到错误,我发现它不受支持。我尝试了您的建议,但出现“'>' 附近的语法错误。我对 SQL Server 中 IIF 语句的语法了解不多,有什么遗漏的吗?
【解决方案2】:

您的代码应该可以在 SQL Server 中运行。我更喜欢这样写:

SELECT c.CustomerID, 
       (CASE WHEN ec.SysCode >= '1747' THEN e.Amount ELSE 0 END) AS Trains
FROM Customer c LEFT JOIN 
     Expense e
     ON c.CustomerID = e.EntityID LEFT JOIN 
     ExpenseCode ec
     ON e.SysCode = ec.SysCode;

这猜测Amount 来自Expense

变化:

  • SQL Server(而不是其他数据库!)需要在多个 JOINs 周围使用那些尴尬的括号。
  • 表别名使查询更易于编写和阅读。
  • CASE 是条件表达式的 SQL 标准,尽管 SQL Server 为 MS Access 兼容性做了“改造”IIF()
  • 限定所有列引用!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多