这个使用条件的case表达式出了什么问题?

use*_*502 1 sql sql-server-2008

我试图在我的查询中的CASE WHEN中做这样的事情,但它没有采用AND部分,它表示语法中的错误,它也不会采取&&.我很感激任何帮助,因为我不是一个SQL大师.

   Total =
               CASE Payment.ID
                    WHEN 1 THEN  mytable.Total
                    WHEN 4 AND trans.Amount IS NULL THEN mytable.Total
                    WHEN 4 AND trans.Amount IS NOT NULL THEN mytable.Total - trans.Amount
                    ELSE '0'
               END,
Run Code Online (Sandbox Code Playgroud)

小智 5

这是一种方法.将表达式更改为类似的内容.

脚本:

Total = (CASE 
            WHEN Payment.ID = 1
                THEN  mytable.Total
            WHEN Payment.ID = 4 
                AND trans.Amount IS NULL 
                    THEN mytable.Total
            WHEN Payment.ID = 4 
                AND trans.Amount IS NOT NULL 
                    THEN mytable.Total - trans.Amount
            ELSE '0'
        END),
Run Code Online (Sandbox Code Playgroud)

有两种类型的CASE表达式即SimpleSearched.您无法在同一表达式中组合Simple和Searched.

简单:

CASE input
    WHEN 1 THEN 'a'
    WHEN 2 THEN 'b'
    WHEN 3 THEN 'c'
    ELSE ''
END
Run Code Online (Sandbox Code Playgroud)

搜索 -Example 1:最简单的形式.

CASE 
    WHEN input = 1 THEN 'a'
    WHEN input = 2 THEN 'b'
    WHEN input = 3 THEN 'c'
    ELSE ''
END
Run Code Online (Sandbox Code Playgroud)

搜索 -Example 2:涉及多个列.您可以在每个WHEN语句中添加多个列.

CASE 
    WHEN input = 1 AND second_column = 2 THEN 'a'
    WHEN input = 2 AND third_column  = 3 THEN 'b'
    WHEN input = 3 AND (second_column = 4 OR third_column = 6) THEN 'c'
    ELSE ''
END
Run Code Online (Sandbox Code Playgroud)


Aar*_*and 5

我认为这是表达相同查询的一种更简单的方法:

Total = CASE Payment.ID
  WHEN 1 THEN myTable.Total
  WHEN 4 THEN myTable.Total - COALESCE(trans.Amount, 0)
  ELSE 0
END,
Run Code Online (Sandbox Code Playgroud)

我们只需要一个条件Payment.ID= 4,因为只有两个可能的结果(我们要么减去trans.Amount或者我们不是,我们可以通过使用COALESCE(或ISNULL)来简化它).当然还有其他表达方式,它们都有其优点.如果myTable.Total实际上是一个更复杂的表达式,那么至少在击键方面它可能更有效率,只提一次表达式,你可以通过稍微改变逻辑来做到这一点:

Total = CASE WHEN Payment.ID IN (1,4)
  THEN myTable.Total - CASE WHEN Payment.ID = 4 THEN
    COALESCE(trans.Amount, 0) ELSE 0 END
  ELSE 0
END,
Run Code Online (Sandbox Code Playgroud)

与原始代码最接近的有效语法是:

Total = CASE 
  WHEN Payment.ID = 1 THEN 
    myTable.Total
  WHEN Payment.ID = 4 AND trans.Amount IS NULL THEN 
    myTable.Total
  WHEN Payment.ID = 4 AND trans.Amount IS NOT NULL NULL THEN
    mytable.Total - trans.Amount
  ELSE
    0
END,
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,你有很多重复,你提到一个表达式三次.在某些情况下,这可能对性能有害(想象一下,如果该表达式计算起来很昂贵,例如子查询或UDF调用,并且查询逻辑导致它被多次计算).有时发动机将会做引擎将要做的事情,不管你试图超越它多少,但如果你不小心的话,你当然可以把它引向错误的道路.

关键是要理解这CASE是一个返回单个值的表达式.许多人来自其他语言,并假设它是一个可用于控制流量的声明.