Get the MAX of combined CASE statements - sql

I have 4 CASE statements and I want to know how can I only display the MAX of the calculation.
I have tried combining my CASE statements with the COALESCE function.
SELECT
ID,
CASE
WHEN tw.displayText IN ('A','B','C') THEN 'A1'
WHEN tw.displayText IN ('D','E','F') THEN 'A2'
WHEN tw.displayText IN ('G','H','I') THEN 'A3'
ELSE NULL
END AS COL1
How can I make COL1 be A3 if the ID can take all 3 (A1,A2,A3)
ID COL1
1 A1
1 A2
1 A3
ID COL1
1 A3

Although the wording of your question is unclear, if my mind-reading skills are on point today, I think this is all you need:
SELECT CASE
WHEN tw.displayText IN ('G','H','I') THEN 3
WHEN tw.displayText IN ('D','E','F') THEN 2
WHEN tw.displayText IN ('A','B','C') THEN 1
ELSE NULL
END AS COL1
Why? Because a single CASE expression is evaluated such that the first WHEN (from top to bottom) to evaluate as true is the one that will be returned by the expression. The rest will be ignored.
So in this expression, if the conditions that would result in a "3" are true, then "3" is returned and the other conditions are ignored. If "3" isn't true, then the conditions for "2" are checked. And so on.
Now if you plan on using GROUP BY and actually getting an Aggregate, then you would need to wrap this entire CASE..END expression in a MAX() function.

SQL Server doesn't have a greatest() or least() function. But you can do this in the from clause using apply:
select COL1
from tw cross apply
(select max(val) as col1
from (values (CASE WHEN tw.displayText IN ('A','B','C') THEN 1 END),
(CASE WHEN tw.displayText IN ('D','E','F') THEN 2 END),
(CASE WHEN tw.displayText IN ('G','H','I') THEN 3 END)
) v(val)
) v;
There may be other ways to phrase this. This is a pretty general solution.

I think you want only one case expression with max() :
SELECT MAX(CASE WHEN tw.displayText IN ('A','B','C') THEN 1
THEN 1
WHEN tw.displayText IN ('D','E','F') THEN 2
THEN 2
WHEN tw.displayText IN ('G','H','I') THEN 3
THEN 3
END) AS COL1
MAX() is really unnecessary because case expression only return single value & will evaluate only once whenever any of them conditions are mat.

Related

How can I use pivot to find the records with the most columns populated?

I have a problem where I have 5 columns.
What I want to do is add a count on the end with the number of columns where there is no null value.
I am trying to use pivot as this seems to be the most logical SQL clause. Any ideas on this? I haven't used Pivot in many instances so this is new for me.
An inline pivot/conditional aggregate and a COUNT seems to be what you want here. As all your columns have different data types, you need to also use some CASE expressions. Something like this:
SELECT ID,
a,
...
(SELECT COUNT(V.C)
FROM (VALUES(CASE WHEN a IS NOT NULL THEN 1 END),
(CASE WHEN b IS NOT NULL THEN 1 END),
(CASE WHEN c IS NOT NULL THEN 1 END),
(CASE WHEN d IS NOT NULL THEN 1 END),
(CASE WHEN e IS NOT NULL THEN 1 END),
(CASE WHEN f IS NOT NULL THEN 1 END))V(C)) AS NonNullColumns
FROM dbo.YourTable;

SQL Case When Statement for Id with multiple rows

I have a table like so
Id Code
1 03J0
1 0304
1 03HI
2 033I
2 03J5
3 03J4
4 030H
I want to do a case when statement, when there is any occurrence where the Id has a Code that is like '%03J' then Happy otherwise Sad. How do I do this when an Id has multiple rows of different codes?
Intended output
Id Emotion
1 Happy
2 Happy
3 Happy
4 Sad
Is this what you want?
select id,
(case when sum(case when code like '03J%' then 1 else 0 end) > 0 then 'Happy' else 'Sad' end) as emotion
from t
group by id;
Using the ordering of strings, you can simplify this to:
select id,
min(case when code like '03J%' then 'Happy' else 'Sad' end) as emotion
from t
group by id;
Here is a db<>fiddle.
Using self-join. Judging from your sampple data, I think you want '03J%' instead of '%03J'
select distinct a.id, case when b.code is not null then 'Happy' else 'Sad' end as emotion
from mytable a
left join mytable b on a.id=b.id and b.code like '03J%';

How to update the following multiple columns scenario using Case?

I have seen case being used for updating one column when conditions are different. My requirement is I have to update 2 columns based on same condition.
Conditions are same for both columns but I want to avoid repetitive query condition.
update t1 set col1= case when col3='A' and col4='AA' then 'A1' else 'B1' end
,col2= case when col3='A' and col4='AA' then 'A2' else 'B2' end
In the above query the conditions for update of the col1 and col2 is same but I have to write it fully write case statement for both columns.
Is there any way to combine the case conditions only one time for two columns?
If your case is long and complicated you could do something like this merge, shorten it in source part to a single value:
merge into t1 t
using (select rowid rwd, case when (col3, col4) in (('A', 'AA')) then 1 else 0 end val from t1) s
on (t.rowid = s.rwd)
when matched then update set
col1 = case val when 1 then 'A1' else 'B1' end,
col2 = case val when 1 then 'A2' else 'B2' end
dbfiddle demo

Check any 4 out 10 conditions are satisfied in SQL

I apologize for asking a very vague question but here it is.
I have to write a SQL query in SQL Server as follows.
I have a table say tblA having 10 columns from col1, col2,.....col10.
Each column is not null and definitely holds some value and all of type int.
The query should be to select all such records in which at least 4 columns are matching with given filter criteria, where the filter criteria has values for all 10 columns.
I googled dint get a clue. It needs to be done in SQL server and single query.
Please suggest.
Thanks in advance.
SELECT *
FROM
yourtable
WHERE
case col1 when #value1 then 1 else 0 end +
case col2 when #value2 then 1 else 0 end +
...
case col10 when #value10 then 1 else 0 end
>=4
You can use CASE expressions to determine if four or more columns match:
SELECT *
FROM YourTable
WHERE CASE WHEN Col1 = Filter1 THEN 1 ELSE 0 END +
CASE WHEN Col2 = Filter2 THEN 1 ELSE 0 END +
....
CASE WHEN Col10 = Filter10 THEN 1 ELSE 0 END >= 4
You can do something like this:
select *
from (select t.*,
(case when col1 <whatever> then 1 else 0 end) as col01_matches,
(case when col2 <whatever> then 1 else 0 end) as col02_matches,
. . .
from t
) t
where (col1_matches + col2_matches + col3_matches . . .) >= 4
This creates a separate indicator variable for each match. You could also do the sum in the subquery, in a single variable. I would prefer to have each match separately, just in case the logic gets more complicated or I want to see what matches.

SQL: Alias Column Name for Use in CASE Statement

Is it possible to alias a column name and then use that in a CASE statement? For example,
SELECT col1 as a, CASE WHEN a = 'test' THEN 'yes' END as value FROM table;
I am trying to alias the column because actually my CASE statement would be generated programmatically, and I want the column that the case statement uses to be specified in the SQL instead of having to pass another parameter to the program.
This:
SELECT col1 as a,
CASE WHEN a = 'test' THEN 'yes' END as value
FROM table;
...will not work. This will:
SELECT CASE WHEN a = 'test' THEN 'yes' END as value
FROM (SELECT col1 AS a
FROM TABLE)
Why you wouldn't use:
SELECT t.col1 as a,
CASE WHEN t.col1 = 'test' THEN 'yes' END as value
FROM TABLE t;
...I don't know.
I think that MySql and MsSql won't allow this because they will try to find all columns in the CASE clause as columns of the tables in the WHERE clause.
I don't know what DBMS you are talking about, but I guess you could do something like this in any DBMS:
SELECT *, CASE WHEN a = 'test' THEN 'yes' END as value FROM (
SELECT col1 as a FROM table
) q
#OMG Ponies - One of my reasons of not using the following code
SELECT t.col1 as a,
CASE WHEN t.col1 = 'test' THEN 'yes' END as value
FROM TABLE t;
can be that the t.col1 is not an actual column in the table. For example, it can be a value from a XML column like
Select XMLColumnName.value('(XMLPathOfTag)[1]', 'varchar(max)')
as XMLTagAlias from Table
It should work. Try this
Select * from
(select col1, col2, case when 1=1 then 'ok' end as alias_col
from table)
as tmp_table
order by
case when #sortBy = 1 then tmp_table.alias_col end asc
I use CTEs to help compose complicated SQL queries but not all RDBMS' support them. You can think of them as query scope views. Here is an example in t-sql on SQL server.
With localView1 as (
select c1,
c2,
c3,
c4,
((c2-c4)*(3))+c1 as "complex"
from realTable1)
, localView2 as (
select case complex WHEN 0 THEN 'Empty' ELSE 'Not Empty' end as formula1,
complex * complex as formula2
from localView1)
select *
from localView2
Nor in MsSql
SELECT col1 AS o, e = CASE WHEN o < GETDATE() THEN o ELSE GETDATE() END
FROM Table1
Returns:
Msg 207, Level 16, State 3, Line 1
Invalid column name 'o'.
Msg 207, Level 16, State 3, Line 1
Invalid column name 'o'.
However if I change to CASE WHEN col1... THEN col1 it works
If you write only equal condition just:
Select Case columns1 When 0 then 'Value1'
when 1 then 'Value2' else 'Unknown' End
If you want to write greater , Less then or equal you must do like this:
Select Case When [ColumnsName] >0 then 'value1' When [ColumnsName]=0 Or [ColumnsName]<0 then
'value2'
Else
'Unkownvalue' End
From tablename
Thanks
Mr.Buntha Khin
SELECT
a AS [blabla a],
b [blabla b],
CASE c
WHEN 1 THEN 'aaa'
WHEN 2 THEN 'bbb'
ELSE 'unknown'
END AS [my alias],
d AS [blabla d]
FROM mytable
Not in MySQL. I tried it and I get the following error:
ERROR 1054 (42S22): Unknown column 'a' in 'field list'
In MySql, alice name may not work, therefore put the original column name in the CASE statement
SELECT col1 as a, CASE WHEN col1 = 'test' THEN 'yes' END as value FROM table;
Sometimes above query also may return error, I don`t know why (I faced this problem in my two different development machine). Therefore put the CASE statement into the "(...)" as below:
SELECT col1 as a, (CASE WHEN col1 = 'test' THEN 'yes' END) as value FROM table;
Yes, you just need to add a parenthesis :
SELECT col1 as a, (CASE WHEN a = 'test' THEN 'yes' END) as value FROM table;
make it so easy.
select columnnameshow = (CASE tipoventa
when 'CONTADO' then 'contadito'
when 'CREDITO' then 'cred'
else 'no result'
end) from Promocion.Promocion