This is my problem: I added a column Cause to my table. This column contains different conditions (up to here, everything is fine). But since I have a lot of lines for each product, it can have 3 conditions at the same time.
What I'm trying to do is that once it finds a condition, it does not go to the one after (and it is by this order of priority).
I do not know if I was clear, but if you want more explanation do not hesitate to ask me questions
Cause = (CASE
WHEN Four IS NOT NULL THEN 'Retards'
WHEN (MAX(DateP BETWEEN '2018-10-24' AND '2018-10-14') THEN 'stock'
WHEN Reference = 0 THEN 'respecté'
WHEN Produit = 2 THEN 'non respecté'
ELSE 'Erreur'
END)
This is an example of what I want to do:
The CASE expression stops just after the first WHEN..THEN is found. If you want to concatenate labels and check all conditions, you can use multiple CASE expression.
(case when Four IS NOT NULL THEN 'Retards' ELSE '' END +
case when (MAX(DateP) between '2018-10-24' AND '2018-10-14') THEN 'stock' ELSE '' END +
case when Reference = 0 THEN 'respecté' ELSE '' END +
case when Produit = 2 THEN 'non respecté' ELSE '' END
) AS Cause
Related
I'm pulling data from an existing table using a stored procedure that has some yes or no choices that the user picks on the front end through a checkbox. I want to limit writing a bunch of different If statements for every choice they make.
This portion of my where clause works. Data is either Y or N for this column.
Where... and IsSigned = Case When #IncludeSigned = 'Y' then IsSigned else 'N' end
I would like to add to the where using is not null and not like if this is possible between the square brackets. So far I have
and SignatureType = case when #IncludeElectronic = 'Y' then Type else [NOT like electronic] end
also
and ReviewDate = Case When #HasReviewDate = 'Y' then [ReviewDate is not null] else null end
This may help you use AND/OR instead of case
where (ReviewDate is not null or #HasReviewDate = 'Y' ) And (....)
ie when #HasReviewDate = 'Y' query will return the records with ReviewDate is not null
and when #HasReviewDate != 'Y' then query will return the records with ReviewDate is null
think of it this way:-
Your first case statement has two possible results:-
IsSigned = 'Y'
IsSigned = 'N'
Your subsequent ones have problems as they don't make sense syntactically. So the second one as written returns
SignatureType = Type
SignatureType = [NOT like electronic]
and your third:
ReviewDate = [ReviewDate is not null]
ReviewDate = null end
SO the operator has to be before the case statement and apply to all of the results of the case statement.
For example
WHERE myfield not like CASE WHEN thatfield=1 THEN 'Fish' ELSE 'Chips END
would produce either
myfield not like 'Fish'
myfield not like 'Chips'
I believe you can not use in this way, apart of that, the impact that is not like can have inside your query can be high, my recommendation changes the strategy that you are using.
So I have EXISTS in huge query which looks like this:
EXISTS(
SELECT
*
FROM
ExistTable
WHERE
ExTableFieldA = #SomeGuid AND
ExTableFieldB = MainTableFieldB AND
ExTableFieldA <> (
CASE
WHEN MainTableFieldZ = 10 THEN MainTableFieldYYY
ELSE NULL
END
)
)
The problem comes from ELSE part of CASE statement, this ExTableFieldA <> NULL will be always false. I could easily write another parameter #EmptyGuid and make it equal to '00000000-0000-0000-0000-000000000000' and everything will work but is this the best approach ?
Pretty much I want to execute another check into the exist for the small size of the records which return the "main" query.
How about removing the case and just using boolean logic?
WHERE ExTableFieldA = #SomeGuid AND
ExTableFieldB = MainTableFieldB AND
(MainTableFieldZ <> 10 OR ExTableFieldA <> MainTableFieldYYY)
I would also recommend that you qualify the column names by including the table alias.
Note: This does assume that MainTableFieldZ is not NULL. If that is a possibility than that logic can easily be incorporated.
ELSE NULL is implied even if you don't list it, but you could use ISNULL here.
ISNULL(ExTableFieldA,'') <> (
CASE
WHEN MainTableFieldZ = 10 THEN MainTableFieldYYY
ELSE ''
END
)
You may need to use some other value like 9999 instead of ''
Recently I've come across a problem with a query that isn't returning everything that it's expected to return. Part of the query which selects by a condition is as follows:
AND field LIKE
CASE WHEN #val = 1 THEN
'%'
ELSE
'N'
END
Now, when #val is 1, I'd expect this piece of code to essentially do nothing, as in the condition to basically accept any value what so ever, including null values.
Am I wrong about this? And if so, does anyone have a solution? I was thinking something along the lines of
AND field LIKE
CASE WHEN #val = 1 THEN
'%' OR ISNULL(field)
ELSE
'N'
END
However SQL doesn't work like that, but that's basically what I wish to accomplish.
Thanks all, and sorry if this is a duplicate, I couldn't find an answer.
Based on what you're trying to accomplish, it seems your query could be optimized to this:
AND (#val = 1 OR field = 'N')
There doesn't seem to be a reason for the LIKE.
UPDATE
Since you are trying to understand the behavior of LIKE and CASE moreso than working with existing queries, here are some variations of the accepted answer.
To use CASE within the LIKE, you have to use something like COALESCE to handle the null case as well.
COALESCE(Field, '') LIKE (CASE WHEN #val = 1 THEN '%' ELSE 'N' END)
Otherwise, you can use the LIKE within the CASE (like accepted answer), but probably personal preference that this seems easier to read:
1 = (CASE WHEN #val = 1 OR Field LIKE 'N' THEN 1 ELSE 0 END)
field LIKE '%' does not match null. CASE expressions must return a single type of result, I like int in most of mine.
AND 1 = CASE
WHEN #val = 1 THEN 1
WHEN field like 'N' THEN 1
ELSE 0
END
Try this (assuming that field is varchar or nvarchar) -
AND ISNULL(field,'') LIKE
CASE WHEN #val = 1 THEN
'%'
ELSE
'N'
END
I am trying to figure out how to turn multiple check box results in differnet fileds into seperate columns.
The current case statement below only tracked the lowest score into a a single filed called 'Activities Registered For (1) – (5)'. I would like to convert them into 5 columns 'a-e' where 'a' is always filled with a result, and if two options are checked the results are in 'a' and 'b'. The form can be filled in with up to all selections checked. The else statement appears to be an error, since there are to be at least one of the five boxes checked.
I am new to SQL and I adopted this from someone else, so I am sorry for not showing my previous attempts to resolve my issue.
,CASE
WHEN [1524#1] = 'Y' THEN '1'
WHEN [1525#1] = 'Y' THEN '2'
WHEN [1526#1] = 'Y' THEN '3'
WHEN [1527#1] = 'Y' THEN '4'
WHEN [1528#1] = 'Y' THEN '5'
ELSE ' ' END AS 'Activities Registered For (1) – (5)'
You could use a PIVOT but multiple CASEs are just as effective, use about the same amount of code and is easier for beginners to decipher.
CASE WHEN [1524#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_1,
CASE WHEN [1525#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_2,
CASE WHEN [1526#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_3,
CASE WHEN [1527#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_4,
CASE WHEN [1528#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_5
I don't think the ELSE is necessarily an error. I often add an ELSE than shouldn't be used in case there is unexpected data (no Y in any field in your example).
Here's some info on PIVOTs if you want to check it out:
http://www.codeproject.com/Tips/500811/Simple-Way-To-Use-Pivot-In-SQL-Query
Why does this case statement not work? My table is defined as below. I want the case to return true when M = "M" or false if it is not. Something does not seem to look right with this CASE statement but this is the simple case statement. But I thought that could be as many WHEN values as needed but in this cases there is only True or False and it does not appear that there could be anything different.
The input should be all of the M column in the row. I am expecting the output to be one row since I only have one row that has an M value in the column. I am not certain if the case statement should return false in this case.
CASE M = "M <-- is this is what the criteria is based on
I found that this is not the case however from the post below. When i meant that this did not look right I was referring two the fact that the WHEN portion of the code
WHEN true THEN something
just did not look like it normally does.
Code:
select CASE M = "M"
WHEN true THEN "PPP"
WHEN false THEN "False -- Look Again!"
ELSE "Not Found"
END
from Bat;
Image:
New Code:
select *,
CASE
WHEN M = 'M' THEN
Case
when O = 'O' then 'you found a double (MM)' <--Compiles but does not show result
End
WHEN M is null THEN 'False -- Look Again!'
END as 'What is this value'
from Bat;
That fixed the first problem but you can embed case statements N deep I would think so if i search again on O it should return a correct. But the first case returns only one record. So my second case would have to search in the record correct.
The normal way to write this is:
select (CASE WHEN M = 'M' THEN 'PPP'
WHEN M <> 'M' THEN 'False -- Look Again!'
ELSE 'Not Found'
END)
from Bat;
or:
select (CASE WHEN M is null then 'Not Found'
WHEN M = 'M' THEN 'PPP'
ELSE 'False -- Look Again!'
END)
from Bat;
If I had to guess, your version has unexpected behavior for NULL values, but it is hard to say without knowing what you expect or what it is doing.
Change it like this
select CASE
WHEN M = 'M' THEN 'PPP'
WHEN M is null THEN 'False -- Look Again!'
ELSE "Not Found"
END
from Bat;