Reputation: 57
Can you teach me what am I doing wrong in my case? :)
I am selecting invoices and repayments.
Error:
Msg 4145, Level 15, State 1, Line 10
An expression of non-boolean type specified in a context where a condition is expected, near 'end'.
Code:
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
Upvotes: 1
Views: 112
Reputation: 12309
The basically use of CASE EXPRESSION is - evaluate some expression, based on the result of expression return the Single Value
Now you almost did correct in WHERE clause. Case Expression returning some values but in WHERE clause that values are need to be compare with some other values and this is missing part in your query . You can try this way as well to get correct result.
...
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
Upvotes: 1
Reputation: 48139
I think you have a total misunderstanding of the WHERE clause. The where clause is a condition of WHAT RECORDS TO BE INCLUDED in the result set. Ex: Give me all records where an invoice is >= some date range, or an invoice where an amount = some value you are looking for. These need to return a logical TRUE or FALSE ONLY.
Using the case statement would be in your field list to identify which VALUE you want back based on the condition. In this case, under the specific conditions of the row you want something specific returned to show the user.
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
Upvotes: 1
Reputation: 4082
The following show how to use search conditions in the 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
Your query is not correct. Query looks like:
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?
Updated
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
)
Upvotes: 1
Reputation: 11
try
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() ;
Upvotes: 1