2016-10-20 3 views
1

Можете ли вы научить меня, что я делаю неправильно в моем случае? :)SQL Server: case when where where where

Я выбираю счета-фактуры и погашения.

Ошибка:

Msg 4145, Level 15, State 1, Line 10
выражение не-логического типа, указанного в контексте, в котором условие, как ожидается, рядом с 'концом'.

Код:

select 
    I.subject1, R.subject2 
from 
    dbo.invoice I 
left join 
    dbo.repayments R on I.subject1 = R.subject2 
where 
    case 
     when R.subject2 is not null and R.remains_due > 0 
      then R.remains_due 
     when R.subject2 is not null and R.remains_due = 0 
      then I.remains_due 
     when R.subject2 is not null and R.due_date <= GETDATE() 
      then R.due_date 
     when R.subject2 is null and I.due_date <= GETDATE() 
      then I.due_date 
    end 
+0

Как правило, лучше использовать 'AND' /' OR' вместо выражений 'case' в предложении' WHERE'. – jarlh

+2

Ваше выражение case возвращает значение, теперь вам нужно сравнить его с чем-то. – jarlh

+0

Мне нужно «дело», потому что «тогда» для меня важно. Сравните вы сказали? Не могли бы вы рассказать мне больше об этом? – otesanek

ответ

0

Следующая показать, как использовать условия поиска WHERE clause.

SELECT 
    ColumnB, 
    ColumnA 
FROM 
    TableA 
WHERE 
    ColumnA = CASE WHEN ColumnB IS NULL THEN 'Test AA' 
        WHEN ColumnB IS NOT NULL THEN 'Test BB' 
        ELSE 'Test CC' END 

Неверный запрос. Запрос выглядит следующим образом:

SELECT 
    ColumnB, 
    ColumnA 
FROM 
    TableA 
WHERE 
    -- Where is ColumnA??? 
    -- Return types must be same type! 
    CASE WHEN ColumnB IS NULL THEN 'Test AA' -- VARCHAR? 
     WHEN ColumnB IS NOT NULL THEN 1 -- INT ? 
     ELSE '2016.10.20' END -- DATETIME? 

Обновлено

select 
    I.subject1, 
    R.subject2 
from 
    dbo.invoice I LEFT join 
    dbo.repayments R on I.subject1 = R.subject2 
WHERE 
    (
     R.subject2 is not NULL AND 
     R.remains_due >= 0 AND 
     R.due_date <= GETDATE() 
    ) OR 
    (
     R.subject2 is NULL AND 
     I.due_date <= GETDATE() AND 
     I.remains_due >= 0 
    ) 
+1

Спасибо за ваш ответ! :) – otesanek

+0

Столбец still_due - это день и дата окончания столбца, дата и время. Должен ли я преобразовать его в varchar? Я не уверен, полностью ли понимаю, что вы ответили. – otesanek

+0

Какие вызовы вы хотите выбрать? – NEER

0

попробовать

select 
    I.subject1, R.subject2 
from 
    dbo.invoice I 
left join 
    dbo.repayments R on I.subject1 = R.subject2 
where 

     R.subject2 is not null and R.remains_due > 0 
      AND 
     R.subject2 is not null and R.remains_due = 0 
      AND 
     R.subject2 is not null and R.due_date <= GETDATE() 
      AND 
     R.subject2 is null and I.due_date <= GETDATE() ; 
+0

Спасибо, но нет логики в состоянии:/ – otesanek

0

Я думаю, что у вас есть полное непонимание ИНЕКЯ. Предложение where является условием WHAT RECORDS, которое должно быть включено в результирующий набор. Пример: дайте мне все записи, где счет-фактура> = некоторый диапазон дат, или счет-фактура, где сумма = какое-то значение, которое вы ищете. Они должны возвращать логическое TRUE или FALSE ONLY.

Использование оператора case будет в вашем списке полей, чтобы определить, какое значение VALUE вы хотите вернуть на основании условия. В этом случае в конкретных условиях строки вы хотите, чтобы что-то конкретное возвращалось, чтобы показать пользователя.

select 
     I.subject1, 
     R.subject2, 
     case when R.subject2 is not null and R.remains_due > 0 
       then R.remains_due 
      when R.subject2 is not null and R.remains_due = 0 
       then I.remains_due 
      end as AmountDue, 
     case when R.subject2 is not null and R.due_date <= GETDATE() 
       then R.due_date 
      when R.subject2 is null and I.due_date <= GETDATE() 
       then I.due_date 
      end DueDate 
    from 
     dbo.invoice I 
     left join dbo.repayments R 
      on I.subject1 = R.subject2 
0

Принципиально использование CASE-выражения является - оценка некоторое выражение, на основе результата выражения возвращают единичное значение

Теперь вы почти сделали правильно в ИНЕКЕ. Case Expression возвращает некоторые значения, но в предложении WHERE значения должны быть сопоставлены с некоторыми другими значениями, и это не учитывает часть вашего запроса. Вы можете попробовать этот путь, чтобы получить правильный результат.

... 
where 
1 = case 
     when R.subject2 is not null and R.remains_due > 0 
     then 1 
     when R.subject2 is not null and R.remains_due = 0 
     then 1 
     when R.subject2 is not null and R.due_date <= GETDATE() 
     then 1 
     when R.subject2 is null and I.due_date <= GETDATE() 
     then 1 
    end 
+0

Спасибо, 1 = случай прохладный. Но ваш код дал мне 0,5 м записей: X – otesanek