Updating column conditional on other columns - sql

My server was crashed, damaging my database. In one of my tables I have an academic_quality column where I store school grades like A, B, C+, D. Somehow, my grades are not distributed through other columns on some rows. I thought I could create a conditional clause and create a new column, academic_quality_new, and update it after checking other columns. I tried the following query but it did not work.
SELECT academic_quality, acceptance_rate, undergrads, setting, environment, degrees_offered,
CASE WHEN (academic_quality OR acceptance_rate OR undergrads OR setting OR environment OR degrees_offered) = 'A' THEN INSERT 'A' INTO academic_quality_new
CASE WHEN (academic_quality OR acceptance_rate OR undergrads OR setting OR environment OR degrees_offered) = 'C' THEN INSERT 'B' INTO academic_quality_new
FROM [school_List_V4]
Any help would be appreciated!

You can try by adding case..when for all available grades.
First you can execute select query and check result
select * ,
case when academic_quality = 'A' OR acceptance_rate = 'A' then 'A'
else case when academic_quality ='B' OR acceptance_rate = 'B' then 'B'
else case when academic_quality = 'C' OR acceptance_rate = 'C' then 'C'
else '--'
end
end
end
from table1
then try this update query, it will update new column. If 2 cases are true then it will take first case, so case on grades should be from highest to lowest.
update table1
set new =
case when academic_quality = 'A' OR acceptance_rate = 'A' then 'A'
else case when academic_quality ='B' OR acceptance_rate = 'B' then 'B'
else case when academic_quality = 'C' OR acceptance_rate = 'C' then 'C'
else '--'
end
end
end
and final updated new column is select * from table1
academic_quality | acceptance_rate | new
A | NULL | A
NULL | B | B
NULL | NULL | --
A | B | A
C | B | B

Related

Sql query to create following tables

use the below table 1 to generate table 2
Table 1
Col1 A B C
------------------
N1 1 0 0
N2 0 1 0
N3 1 0 0
Table 2
output
new_col
-------
N1 A
N2 B
N3 A
Also how to use Table 2 to generate table 1 above
Following SQL query can be help to get requested output:
SELECT Col1,IF(A=1,'A',IF(B=1,'B','C')) AS result FROM `table_name`;
You can use conditinal with CONCAT() Function :
SELECT CONCAT(col1,' ',
CASE WHEN A = 1 THEN 'A' ELSE '' END,
CASE WHEN B = 1 THEN 'B' ELSE '' END,
CASE WHEN C = 1 THEN 'C' ELSE '' END)
FROM table1
provided you're on a DBMS with brand name such as MySQL, PostGRES, SQL Server. As an example, Oracle DB won't allow using more than two arguments for CONCAT() Function.
In order to create table2, use for most of the DBMS :
CREATE TABLE table2 AS
SELECT CONCAT(col1,' ',
CASE WHEN A = 1 THEN 'A' ELSE '' END,
CASE WHEN B = 1 THEN 'B' ELSE '' END,
CASE WHEN C = 1 THEN 'C' ELSE '' END) AS new_col
FROM table1
except for SQL Server in which prefer using :
SELECT CONCAT(col1,' ',
CASE WHEN A = 1 THEN 'A' ELSE '' END,
CASE WHEN B = 1 THEN 'B' ELSE '' END,
CASE WHEN C = 1 THEN 'C' ELSE '' END) AS new_col
INTO table2
FROM table1
In order to implement a reverse engineering(go back to original table), you need to consider the dialectics for each seperate database to handle string values. Assume you're using MySQL DB, then consider using :
CREATE TABLE table3 AS
SELECT SUBSTRING(new_col,1,instr(new_col,' ')-1) AS col1,
CASE WHEN instr(new_col,'A') > 0 THEN 1 ELSE 0 END AS A,
CASE WHEN instr(new_col,'B') > 0 THEN 1 ELSE 0 END AS B,
CASE WHEN instr(new_col,'C') > 0 THEN 1 ELSE 0 END AS C
FROM table2
where I used a different table name (table3), since table1 already exists.
Demo
Btw, if Oracle DB is the case, then use :
SELECT CONCAT(CONCAT(col1,' '),
CASE WHEN A = 1 THEN 'A' ELSE '' END||
CASE WHEN B = 1 THEN 'B' ELSE '' END||
CASE WHEN C = 1 THEN 'C' ELSE '' END) AS new_col
FROM table1
You can use one case statement. This works in Oracle.
SELECT col1
|| CASE
WHEN A = 1
THEN 'A'
WHEN B = 1
THEN 'B'
WHEN C = 1
THEN 'C'
END
NEW_COL
FROM table1
It is unclear what you want when there are multiple "1"s in a row. This is a simple solution:
select id, A from t where A = 1
union all
select id, B from t where B = 1
union all
select id, C from t where C = 1;
In databases that support lateral joins, I would recommend:
select t.id, v.which
from t cross join lateral
(values ('A', t.A), ('B', B), ('C', C)
) v(which, val)
where val = 1;

case statement to find one value

I'm trying to show one row per id but it is returning three.
If the id has a 'y' then it should show a 'y'.
If it shows a 'y' and 'r' it should be 'y'.
If it has 'y', 'r', 'n' it should be 'y'.
If it is just id and 'r' it should be 'r' and id and just 'n' then 'n'.
I can't seem to get it to work using a case statement. Any ideas? Thanks.
I've tried this:
,CASE WHEN result = 'Y' THEN 'Y'
WHEN result = 'Y' AND result = 'R') THEN 'Y'
WHEN result = 'R' THEN 'R'
ELSE 'N' END AS CARE_PLAN
What it is returning:
ID result
3434 'y'
3434 'r'
3434 'n'
You can use Listagg function,
Writing a subquery and DISTINCT then use Listagg function.
SELECT id, Listagg (result, ', ')
within GROUP (ORDER BY result) as CARE_PLAN
FROM (SELECT DISTINCT id,
( CASE
WHEN result = 'Y' THEN 'Y'
WHEN result = 'Y'
AND result = 'R' THEN 'Y'
WHEN result = 'R' THEN 'R'
ELSE 'N'
END ) AS result
FROM t) T
GROUP BY id
sqlfiddle:http://sqlfiddle.com/#!4/02cd5/2
[Results]:
| ID | CARE_PLAN |
|------|-----------|
| 1234 | N, R, Y |
It shall be proper to use ASCII and CHR functions for your case instead of using CASE .. WHEN, as in the following :
SELECT ID, CHR(MAX(ASCII(result))) AS CARE_PLAN
FROM TAB
GROUP BY ID
ORDER BY ID;
SQL Fiddle Demo
You would seem to want aggregation with some conditional logic:
select id,
(case when sum(case when result = 'y' then 1 else 0 end) > 0 then 'y'
when sum(case when result = 'r' then 1 else 0 end) > 0 then 'r'
when min(result) = max(result) and min(result) = 'n' then 'n'
else '?'
end) as new_result
from t
group by id;
If there are only those three values, then perhaps this simplified logic works:
select id, max(result) as new_result
from t
group by id;

simplify multiple union in sql

i am trying to simply the following union query .Basically i am trying to get all the possible values from same table different column and i have to take value which are not equal to no then replace them with specific text when they are from respective column.
select 'a' from Mytable where a!='no' and id='1'
union
select 'b' from Mytable where b!='no' and id='1'
union select 'c' from Mytable where c!='no' and id='1'
so my table structure will be
id Acolumn BColumn Ccolumn
1 123a no 345v
so my expected result is
a c
so please suggest me to simplify this query thanks in advance
According to what you've written, this might be OK.
select case when a <> 'no' and id = '1' then 'a'
when b <> 'no' and id = '1' then 'b'
when c <> 'no' and id = '1' then 'c'
end
from mytable
where (a <> 'no' and id = '1')
or (b <> 'no' and id = '1')
or (c <> 'no' and id = '1')

SQL Server CASE statement with mupltiple conditionals syntax

I have a need to add a case statement into a select, but I cannot seem to get the syntax right, could anyone help?
SELECT
uuid = pnt.ID
,extras = (CASE (SELECT pnt.TypeID as [type], pnt.Source as source)
WHEN source = 7 THEN 'a'
WHEN source = 1 AND [type] = 0 THEN 'b'
WHEN source = 8 THEN 'c'
WHEN source = 2 AND [type] = 0 THEN 'd'
WHEN source = 3 AND [type] IN (5,6,7,8) THEN 'e'
ELSE NULL
END)
FROM
Mydata as pnt
There are multiple problems, the select within the case is incorrect, the condition source = 7 is wrong, the combining conditions with an AND is wrong and the condition using IN is incorrect.
I used the answer to Multiple Criteria In Case Statement as a basis for the case statement.
SELECT
#uuid = pnt.ID
,#extras = (CASE WHEN source = 7 THEN
'a'
WHEN source = 1 AND [type] = 0 THEN
'b'
WHEN source = 8 THEN
'c'
WHEN source = 2 AND [type] =0 THEN
'd'
WHEN source = 3 AND [type] IN (5,6,7,8) THEN
'e'
ELSE NULL
END
)
FROM
Mydata as pnt
There are two types of case statements:
A simple case statement that compares an expression to a set of simple expressions to return specific values.
A searched case statement that evaluates a set of Boolean expressions to return specific values.
https://msdn.microsoft.com/en-us/library/ms144841(v=sql.105).aspx
In your script your're "mixing" them, so that your script doesn't work.
This could be a good solution:
SELECT
pnt.ID
,CASE
WHEN pnt.source = 7 THEN 'a'
WHEN pnt.source = 1 AND pnt.TypeID = 0 THEN 'b'
WHEN pnt.source = 8 THEN 'c'
WHEN pnt.source = 2 AND pnt.TypeID = 0 THEN 'd'
WHEN pnt.source = 3 AND pnt.TypeID IN (5, 6, 7, 8) THEN 'e'
ELSE NULL
END
FROM
#Mydata AS pnt
Warning!
If you need to populate single variables (uuid, extras) you have to be sure that your query's result will have only 1 record
SELECT
PNT.ID AS UUID
, CASE
WHEN PNT.source = 7 THEN 'a'
WHEN PNT.source = 1 AND PNT.[type] = 0 THEN 'b'
WHEN PNT.source = 8 THEN 'c'
WHEN PNT.source = 2 AND PNT.[type] = 0 THEN 'd'
WHEN PNT.source = 3 AND PNT.[type] IN (5, 6, 7, 8) THEN 'e'
ELSE NULL
END AS EXTRAS
FROM Mydata AS PNT
As you are already working within the table Mydata a case expression has access to the values held in [source] and [type] without an added select.
I have put the column aliases at the end of each column definition, I believe this is more generally supported by databases than using = for that purpose.
SELECT ID As uuid, CASE WHEN Source = 7 THEN
'a'
WHEN Source = 1 AND TypeID= 0 THEN
'b'
WHEN Source = 8 THEN
'c'
WHEN Source = 2 AND TypeID= 0 THEN
'd'
WHEN Source = 3 AND TypeID IN (5,6,7,8) THEN
'e'
ELSE
NULL
END
AS extras FROM Mydata

counting records on the same table with different values possibly none sql server 2008

I have a inventory table with a condition i.e. new, used, other, and i am query a small set of this data, and there is a possibility that all the record set contains only 1 or all the conditions. I tried using a case statement, but if one of the conditions isn't found nothing for that condition returned, and I need it to return 0
This is what I've tried so far:
select(
case
when new_used = 'N' then 'new'
when new_used = 'U' then 'used'
when new_used = 'O' then 'other'
end
)as conditions,
count(*) as count
from myDB
where something = something
group by(
case
when New_Used = 'N' then 'new'
when New_Used = 'U' then 'used'
when New_Used = 'O' then 'other'
end
)
This returns the data like:
conditions | count
------------------
new 10
used 45
I am trying to get the data to return like the following:
conditions | count
------------------
new | 10
used | 45
other | 0
Thanks in advance
;WITH constants(letter,word) AS
(
SELECT l,w FROM (VALUES('N','new'),('U','used'),('O','other')) AS x(l,w)
)
SELECT
conditions = c.word,
[count] = COUNT(x.new_used)
FROM constants AS c
LEFT OUTER JOIN dbo.myDB AS x
ON c.letter = x.new_used
AND something = something
GROUP BY c.word;
try this -
DECLARE #t TABLE (new_used CHAR(1))
INSERT INTO #t (new_used)
SELECT t = 'N'
UNION ALL
SELECT 'N'
UNION ALL
SELECT 'U'
SELECT conditions, ISNULL(r.cnt, 0) AS [count]
FROM (
VALUES('U', 'used'), ('N', 'new'), ('O', 'other')
) t(c, conditions)
LEFT JOIN (
SELECT new_used, COUNT(1) AS cnt
FROM #t
--WHERE something = something
GROUP BY new_used
) r ON r.new_used = t.c
in output -
new 2
used 1
other 0
You can do it as a cross-tab:
select
sum(case when new_used = 'N' then 1 else 0 end) as N,
sum(case when new_used = 'U' then 1 else 0 end) as U,
sum(case when new_used = 'O' then 1 else 0 end) as Other
from myDB
where something = something