Adding a condition to the showcase - sql

The task is as follows. I have a code that has a huge number of attributes. And to one of the attributes, let's say this is the card type card_type='universal', you need to add the following condition:
case when card>='129897' and card<='293965'then 'unnamed' and card>='093750' and card <='903750' then 'personal' end as parameter
The attribute itself is as follows :select case when card_sybtype in ('VISA','MS') then 'universal'
At the same time, I do not need to output this to the final script, but I need this feature to be present in the script. That is, I need it to be linked only to the card type.

I think you can use a nested case when.
And if you dont want to select parameter column, you can use a subquery to hide the columns. So, in case you want it, just add it to the outside select list.
SELECT col1, col2
FROM
(SELECT
col1, col2,
case when card_sybtype in ('VISA','MS') THEN -- universal case
case when card>='129897' and card <='293965' then 'unnamed'
when card>='093750' and card <='903750' then 'personal' end
else null
end as param_adhoc
FROM tab
) rs

Related

Can I use different selection comparisons based on a passed value in SQL?

I wasn't really sure of the best wording for the question but here is my dilemma:
I am passing a value to a sql query as #district. This value may be the exact district but it also has the possibility of being a value that should create a set of multiple districts. So if I pass 002 I want the WHERE clause to say I.Offense_Tract = #district. If I pass Other I want the WHERE clause to say I.Offense_Tract in (). What I am trying to do is something like:
AND
CASE
WHEN #district = "Other" THEN I.Offense_Tract in ('BAR','COL','GER','MEM','MIL','JAIL','JAILEAST','SCCC','1USD','2USD')
ELSE I.Offense_Tract = #district
END
But this doesn't work. The problem, restated, is if the value passed is anything other than Other, I just want it to be =. If Other is passed, I want it to be IN.
You don't need the CASE expression.
You can apply this logic with operators AND and OR:
AND (
(#district = 'Other' AND I.Offense_Tract IN ('BAR','COL','GER','MEM','MIL','JAIL','JAILEAST','SCCC','1USD','2USD'))
OR
(#district <> 'Other' AND I.Offense_Tract = #district)
)
Note that, in databases like MySql, Postgresql and SQLite, your code would work as it is.

Force result for field as 'NULL' when document was posted after a certain date

I have a query that I am pulling in a department field, however, after a certain date I want this field to be populated as null.
For example, here is the code
Select T6.Segment2 as 'Old Department Code'
I do want this field to pull in the appropriate values, however after a certain date ( 04/01/2019 ) I want this field to show a NULL value.
Is this possible?
Not sure which DBMS you are using but it is basically the same for all of them when it comes to this... You want to use a CASE statement.
What this essentially does is it acts as an IF ELSE in your SELECT.
So in your case (ha, pun) (T-SQL Syntax):
SELECT
CASE
WHEN (YourDateFieldHere) < '04/01/2019' THEN (YourOutputFieldHere)
ELSE NULL
END (AS Alias)
FROM ...
CASE statements can check for multiple criteria, it doesn't have to just be one or the other, in this case just include more lines of WHEN (something) THEN (display this)
You can use case..when
( considering YYYYMMDD is the default format used in SAP at the internal level )
Select case when myDate >'20190104' then
null
else
T6.Segment2
end
as 'Old Department Code'
From yourTable

Mutliple values for IN clause with CASE in Redshift

I am trying to run this query where IN clause uses CASE to choose values between two cases.
The issue is with the hard coded value('aaa','bbb'). I cannot add multiple values inside THEN so it act as regular IN values. The hard code values will be dynamic as I will pass a variable for it.
select kdo.field0
from tb1 data1 inner join tb2 kdo
on kdo.field1 = 'xxx'
and kdo.field2::DATE >='2017-08-01'::DATE
and kdo.field0
in (case when 'asd'!='' then 'aaa','bbb'
else tb2.field0 end);
Also, I used a sub-query select inside THEN to get specific hard code values but it is also of no avail. Using single hard-coded value obviously works as usual.
Move your CASE outside IN:
select kdo.field0
from tb1 data1 inner join tb2 kdo
on kdo.field1 = 'xxx'
and kdo.field2::DATE >='2017-08-01'::DATE
and case when 'asd'!='' then kdo.field0 in ('aaa','bbb')
else kdo.field0=tb2.field0 end;
however I'm not sure what do you mean by 'asd'!='' since 'asd' is a string and this will always return true
also, else tb2.field0 end); part in your statement is not an array option, it's a column name so I assume this just translates to kdo.field0=tb2.field0 because if the previous case option is false you want to check if kdo.field0 is equal to any of values in tb2.field0 which is basically a join condition

AND statement inside CASE postgreSQL referring to similar condiitons

I am trying to use an AND statement inside a CASE statement, referring to the same thing twice:
CASE
WHEN col1 like A then col_A-(col_B/col_C)
WHEN col1 like A AND sum(col2)=0 then col_D
end as casecolumn
However I am finding that only the first WHEN statement is affecting the column, i.e only calculation1 is implemented, how can I make sure both calculations are applied to casecolumn?
Switch the order of the conditions:
CASE WHEN col1 like A AND SUM(col2) = 0 THEN calcuation2
WHEN coc1 like A THEN calculation1
END AS casecolumn
If the LIKE and SUM criteria be met first, that condition would fire. Otherwise, the CASE expression will flow down to the more lenient criteria for another chance to match.
If you want the "calculation" of both conditions to be applied should both the LIKE and SUM conditions be true, then just use it when determining the value for that condition.

Assign a case value to a column rather than an alias

This should be a simple one, but I have not found any solution:
The normal way is using an alias like this:
CASE WHEN ac_code='T' THEN 'time' ELSE 'purchase' END as alias
When using alias in conjunction with UNION ALL this causes problem because the alias is not treated the same way as the other columns.
Using an alias to assign the value is not working. It is still treated as alias, though it has the column name.
CASE WHEN ac_code='T' THEN 'time' ELSE 'purchase' END as ac_subject
I want to assign a value to a column based on a condition.
CASE WHEN ac_code='T' THEN ac_subject ='time' ELSE ac_subject='purchase' END
Now I get the error message
UNION types character varying and boolean cannot be matched
How can I assign a value to a column in a case statement without using an alias in the column (shared by other columns in UNION)?
Here is the whole (simplified) query:
SELECT hr_id,
CASE WHEN hr_subject='' THEN code_name ELSE hr_subject END
FROM hr
LEFT JOIN code ON code_id=hr_code
WHERE hr_job='123'
UNION ALL
SELECT po_id,
CASE WHEN po_subject='' THEN code_name ELSE po_subject END
FROM po
LEFT JOIN code ON code_id=po_code
WHERE po_job='123'
UNION ALL
SELECT ac_id,
CASE WHEN ac_code='T' THEN ac_subject='time' ELSE ac_subject='purchase' END
FROM ac
WHERE ac_job='123'
There is no alias in your presented query. You are confusing terms. This would be a column alias:
CASE WHEN hr_subject='' THEN code_name ELSE hr_subject END AS ac_subject
In a UNION query, the number of columns, column names and data types in the returned set are determined by the first row. All appended rows have to match the row type. Column names in appended rows (including aliases) are just noise and ignored. Maybe useful for documentation, nothing else.
The = operator does not assign anything in a SELECT query. It's the equality operator that returns a boolean value. TRUE if both operands are equal, etc. This returns a boolean value: ac_subject='time' Hence your error message:
UNION types character varying and boolean cannot be matched
The only way to "assign" a value to a particular output column in this query is to include it at the right position in the SELECT list.
The information in the question is incomplete, but I suspect you are also confusing the empty string ('') with the NULL value. A distinction that you need to understand before doing anything else with relational databases. Maybe start here. In this case you would rather use COALESCE to provide a default for NULL values:
SELECT hr_id, COALESCE(hr_subject, code_name) AS ac_subject
FROM hr
LEFT JOIN code ON code_id=hr_code
WHERE hr_job = '123'
UNION ALL
SELECT po_id, COALESCE(po_subject, code_name)
FROM po
LEFT JOIN code ON code_id=po_code
WHERE po_job = '123'
UNION ALL
SELECT ac_id, CASE WHEN ac_code = 'T' THEN 'time'::varchar ELSE 'purchase' END
FROM ac
WHERE ac_job = '123'
Just an educated guess, assuming type varchar. You should have added table qualification to column names to clarify their origin. Or table definitions to clarify everything.
The CASE expression is supposed to return a value, e.g. 'time'.
Your value is another expression subject ='time' which is a boolean (true or false).
Is this on purpose? Does the other query you glue with UNION have a boolean in that place, too? Probably not, and this is what the DBMS complains about.
I found the problem.
CASE WHEN hr_subject=’’ THEN code_name ELSE hr_subject END
The columns code_name and hr_subject was different length. This caused the unpredictable result. I think that aliases can work now.
Thank you for your support.