How to update the following multiple columns scenario using Case? - sql

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

Related

Get the MAX of combined CASE statements

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.

Multiple Case Statements - Function/Sproc

I wish to create a table with many fields. And I need to do multiple case statement on each field. Please help me with a clean way (Function/Stored Proc) to do it, instead of writing case statement over and over.
Below is an example SQL.
SELECT
COALESCE(CASE WHEN Col1 = 'XXX' THEN 'YYY' ELSE NULL END,
CASE WHEN Col1 IN ('AAA','BBB') AND Col2 IS NULL THEN 'ZZZ' ELSE NULL END,
CASE WHEN Col1 = 'CCC' THEN 'DDD' ELSE Col2 END ) AS col_i
.
.
.
FROM table
Within a single query, you can use apply (or a subquery or CTE):
SELECT v.col_i
FROM table t CROSS APPLY
(VALUES (CASE . . . )
) v(col_i)
If you want this generally available, then don't use a function, use a computed column:
alter table t add col_i as
(case . . . );
This would then be available to anyone using the table.
I think we can rewrite your logic into a single CASE expression:
CASE WHEN Col1 = 'XXX'
THEN 'YYY'
WHEN Col1 IN ('AAA', 'BBB') AND Col2 IS NULL
THEN 'ZZZ'
WHEN Col1 = 'CCC'
THEN 'DDD'
ELSE Col2 END
What makes this work is that your ELSE values are NULL (except for the very last CASE expression), which logically means that COALESCE would just rollover to the next CASE expression.

select in case or if statement?

Is it possible to add a select statement in case or if function in SQL
select case when :A='do' then (select col1 from table1) else 'n/a' end;
or
select if(:A='do',(select col1 from table1),'N/A');
If my parameter is 'do' it should display all the value in table or else it should just display 'N/A'.
Please help me. Thanks!
If this is Oracle, as per your tag, then neither of your queries are valid as they're not actually selecting from a table.
Perhaps what you're after is something like:
select case when :A='do' then col1 else 'n/a' end col
from table1;
Or maybe you're after something like:
select col1
from table1
where :A != 'do'
union all
select 'N/A' col1
from dual
where :A = 'do';
You didn't provide any example data, so I'm not sure if what you're trying to do is make all the values of col1 appear as 'N/A' if the bind variable is "do" or whether you only want a single row containing 'N/A'.

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

How to choose a columns of a select statement based on conditions?

I have to create an SQL Server 2005 query which checks for the value of one attribute in the table and based on its value, select different sets of columns.
How can I do that?
for e.g.
In table 'car', if the values of 'type' attribute are 1 and 2
when type = 1, i want to execute a select 'query1' with 3 columns.
when type = 2, i want to execute another select 'query2' with 4 other columns.
How do I do that?
Please help.
I think you're looking at a Stored Procedure with an If statement. CASE will work, but it can't change the number of columns returned.
SELECT
Col1 = CASE WHEN Type = 1 THEN (SELECT Null FROM T1)
ELSE (SELECT Col1 FROM T2) END
, Col2 = CASE WHEN Type = 1 THEN (SELECT Col1 FROM T1)
ELSE (SELECT Col2 FROM T2) END
, Col3 = CASE WHEN Type = 1 THEN (SELECT Col2 FROM T1)
ELSE (SELECT Col4 FROM T2) END
, Col4 = CASE WHEN Type = 1 THEN (SELECT Col3 FROM T1)
ELSE (SELECT Col4 FROM T2) END
FROM Cars
If you would show us the DDL of all tables involved, you'd probably get a better answer or a different (read better) approach.