2012-04-29 2 views
1

Я пытаюсь сделать что-то подобное в CASE КОГДА в моем запросе, но он не принимает часть И, он говорит о своей ошибке в синтаксисе, он не принимает & &. Я был бы признателен за любую помощь, поскольку я не очень люблю гуру 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, 
+0

На самом деле, я не вижу здесь каких-либо переменных, ошибок в заголовке или не оставлял или менял часть вашего кода? –

+0

Нет, я думаю, что кто-то изменил его для меня ... – user710502

+0

Я изменил его .. не знаю, кто его изменил, чтобы сказать, что я использовал «переменные» – user710502

ответ

5

Вот один из способов сделать это. Измените выражение на что-то вроде этого.

Script:

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), 

Есть два типа выражения CASE, а именно Simple и Searched. Вы не можете комбинировать Simple и Searched в одном выражении.

Простой:

CASE input 
    WHEN 1 THEN 'a' 
    WHEN 2 THEN 'b' 
    WHEN 3 THEN 'c' 
    ELSE '' 
END 

Искал - Example 1: В простейшей форме.

CASE 
    WHEN input = 1 THEN 'a' 
    WHEN input = 2 THEN 'b' 
    WHEN input = 3 THEN 'c' 
    ELSE '' 
END 

Искал - 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 
+0

Возможно, стоит отметить преимущество * search * - что условия не все должны включать один и тот же столбец ('input') и могут быть сколь угодно сложными. –

5

Я думаю, что это гораздо более простой способ выразить тот же запрос:

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

Мы только действительно нужно одно условное для 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, 

ближайший действительный синтаксис исходного кода:

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, 

Но в этом случае у вас есть много повторения там, и вы упоминаете одно выражение в три раза. В некоторых случаях это может нанести ущерб производительности (предположим, что это выражение было дорого рассчитать, например, запрос подзапроса или UDF, а логика запроса заставляла его вычислять более одного раза). Иногда двигатель собирается делать то, что движок собирается делать, независимо от того, сколько вы пытаетесь перехитрить его, но вы, безусловно, можете привести его к неправильному пути, если не будете осторожны.

Ключ должен понимать, что CASE - это выражение, которое возвращает одно значение. Многие люди приходят с других языков и считают, что это утверждение, которое может использоваться для контроля потока.

+0

Ваш «более простой» запрос вычитает trans.Amount, когда он не должен - в частности, когда Payment.ID = 1. Если я не пропустил что-то в этом вопросе, более простой запрос даст неправильный результат, когда ID = 1 и Amount isn ' t null или ноль. –

+0

Полностью правый Стив, хорошая добыча! Полностью удалена эта версия. –

+0

Что делает COALESCE? – user710502