Replace column values - sql

I've got this table,
Name Rating
A 2
B 1
C 5
D 3
E 1
F 4
and I've got a rating system
1-Excellent, 2-Very Good, 3-Good, 4-OK, 5-Poor
I was wondering if i could replace the nueric values in the table to get the following result table.
Name Rating
A Very Good
B Excellent
C Poor
D Good
E Excellent
F OK
Thanks

I don't think it's good idea to update your data inplace, it's better to store id of the rating and not text representation of the data. But you can query your table and replace int with text:
select
Name,
case Rating
when 1 then 'Excellent'
when 2 then 'Very Good,'
when 3 then 'Good'
when 4 then 'OK'
when 5 then 'Poor'
end as Rating
from <your table>
Or you can create a lookup table and join with it
create table Rating (id int, desc nvarchar(128))
insert into Rating (id, desc)
select 1, 'Excellent' union all
select 2, 'Very good' union all
select 3, 'Good' union all
select 4, 'OK' union all
select 5, 'Poor'
select
t.Name,
R.desc as Rating
from <your table> as t
left outer join Rating as R on R.id = t.Rating

Use a CASE statement. Of course, this will only work if your column is not set to a numeric value.
UPDATE tblRatings
SET Rating = CASE WHEN 1 THEN 'Excellent'
WHEN 2 THEN 'Very Good'
WHEN 3 THEN 'Good'
WHEN 4 THEN 'OK'
ELSE 'Poor'
END
If it is, you'll need to use a SELECT statement;
SELECT CASE WHEN 1 THEN 'Excellent'
WHEN 2 THEN 'Very Good'
WHEN 3 THEN 'Good'
WHEN 4 THEN 'OK'
ELSE 'Poor'
END
FROM tblRatings

Try using Choose
IF sql-server 2012
like this:
select Rating,name,choose(Rating,'Excellent','Very Good','Good','OK','Excellent','Poor') from table
Fiddle Demo

You can use update function :
update yourtable set rating = 'Excellent' where rating = '1'
and zou can do this update for all your ratings

Update YOURTABLE
set Rating = case when '2' then ' Very good'
when '3' then ' good' end

Related

how can I add a new column where there may be matches on an id field

I currently have a table that contains an id, and a count of a criteria for that id field. For example my table looks like this:
ID Banana_count
1 13
2 23
3 56
The original counts came from a join and a query from other tables.
create FRUIT_TABLE as
select id, count (fruit)
from my_table a
where exists (select null from DATE_FED b
where a.id = b.id
and date = (2/11/17)
and fruit_type = 'banana')
group by id;
My question is, how can i add other attributes to this particular table so that it looks like:
ID Banana_count Apple_count Orange_count
1 13 35 22
2 23 44
3 56
4 33 55
5 11
I will have to add more ids to FRUIT_TABLE that may not already be in the current table, but for fruits that are currently associated with an id, i'd like to add them in the same row.
This is a classic use case for merge:
merge into fruit_table
using apple_table
on (fruit_table.id = apple_table.id)
when matched then update set
fruit_table.apples = apple_table.apples
when not matched then insert (id,apples)
values(
apple_table.id,
apple_table.apples
);
I have simplified the problem slightly so that you are inserting from a table that simply has ids and a count of apples, so that the structure of the merge is clearer. But you can insert a subquery instead into the using... section of the statement to meet your actual requirements.
I would look into something like the following [you didn't provide your table definitions, or other application or requirements constraints so an exact answer is not possible]:
create FRUIT_TABLE as
select id
, sum(case when fruit_type = 'banana' then 1 else 0 end ) Banana_count
, sum(case when fruit_type = 'apple' then 1 else 0 end ) apple_count
, sum(case when fruit_type = 'orange' then 1 else 0 end ) orange_count
from my_table a
group by id;

SQL SELECT Query with group and distinct

I have table with 4 columns (id, bm, name, act).
I want to retrieve records grouped by bm and count how many records have of every group where act = no and where act = yes at once...
So if I have records:
(Id, bm, name, act)
1, 5, Nik, yes
2, 6, Mike, yes
3, 5, Tom, no
4, 5, Alex, no
Result I need is:
(bm, totalYes, totalNo)
5, 1, 2
6, 1, 0
I guess that everything is possible to retrieve from SQL but I don't know how :(
You can use conditional aggregation to achieve this result:
select
bm,
sum(case when act = 'yes' then 1 else 0 end) as "Count of yes",
sum(case when act = 'no' then 1 else 0 end) as "Count of no"
from t
group by bm;
With some databases, like MySQL, you can reduce the aggregation to sum(act = 'yes'), but the ANSI SQL standard requires the full case expression.
Sample SQL Fiddle
Try following
SELECT SUM(CASE WHEN act = 'no' THEN 1 ELSE 0 END) as NoCount,
SUM(CASE WHEN act = 'yes' THEN 1 ELSE 0 END) YesCount
FROM tbl
GROUP BY gm
Since aggregate functions typically skip nulls, you can create two columns TotalYes and TotalNo, with a value NULL for cases you don't want to include in your count.
Here's what I mean:
SELECT
bm,
COUNT( CASE act WHEN 'yes' THEN 1 ELSE NULL END ) TotalYes,
COUNT( CASE act WHEN 'no' THEN 1 ELSE NULL END ) TotalNo
FROM tbl
GROUP BY bm

SQL AVG with Case

I've a DB which stores a value from C to AAA, while C is the worst and AAA the best.
Now I need the average of this value and I don't know how to first convert the values into an int, calculate the average, round the average to an int and convert it back.
Definitions:
C = 1
B = 2
A = 3
AA = 4
AAA = 5
Is that even possible with an SQL statement? I tried to combine AVG and CASE, but I don't bring it to work...
Thanks for your help!
Regards,
select avg(case score
when 'C' then 1
when 'B' then 2
when 'A' then 3
when 'AA' then 4
when 'AAA' then 5
end) as avg_score
from the_table;
(this assumes that the column is called score)
To convert this back into the "character value", wrap the output in another case:
select case cast(avg_score as int)
when 1 then 'C'
when 2 then 'B'
when 3 then 'A'
when 4 then 'AA'
when 5 then 'AAA'
end as avg_score_value
from (
select avg(case score
when 'C' then 1
when 'B' then 2
when 'A' then 3
when 'AA' then 4
when 'AAA' then 5
end) as avg_score
from the_table;
) t
The above cast(avg_score as int) assumes ANSI SQL. Your DBMS might have different ways to cast a value to an integer.
I've created this example for u.
u can cast ur ranking into temp table, then calculate and when ur done, drop it.
create table sof (id int identity,a nvarchar (10))
insert into sof values ('a')
insert into sof values ('b')
insert into sof values ('c')
select case a when 'AAA ' then 5
when 'AA' then 4
when 'A' then 3
when 'B' then 2
else 1
end as av
into #temp
from sof
----for rounded
select ROUND(AVG(CAST(av AS FLOAT)), 4)
from #temp
--not rounded
select AVG (av)
from #temp

Select Distinct Attribute and Print out Count of another even when the count is 0

I don't quite know how I should describe the problem for title, but here's my question.
I have a table named hello with two columns named time and state.
Time | State
Here's an example of the data I have
1 DC
1 VA
1 VA
2 DC
2 MD
3 MD
3 MD
3 VA
3 DC
I would like to get all the possible time and the count of "VA" (0 if "VA" doesn't appear at the time)
The output would look like this
Time Number
1 2
2 0
3 1
I tried to do
SELECT DISTINCT time,
COUNT(state) as Number
FROM hello
WHERE state = 'VA'
GROUP BY time
but it doesn't seem to work.
This is a conditional aggregation:
select time, sum(case when state = 'VA' then 1 else 0 end) as NumVA
from hello
group by time
I want to add that you should never use distinct when you have a group by. The two are redundant. Distinct as a keyword is not even needed in the SQL language; semantically, it is just shorthand for grouping by all the columns.
SELECT TIME,
SUM(CASE WHEN State = 'VA' THEN 1 ELSE 0 END)
FROm tableName
GROUP BY Time
SQLFiddle Demo
One rule of thumb is to get your counts first and put them into a temp for use later.
See below:
Create table temp(Num int, [state] varchar(2))
Insert into temp(Num,[state])
Select 1,'DC'
UNION ALL
Select 1,'VA'
UNION ALL
Select 1,'VA'
UNION ALL
Select 2,'DC'
UNION ALL
Select 2,'MD'
UNION ALL
Select 3,'MD'
UNION All
Select 3,'MD'
UNION ALL
Select 3,'VA'
UNION ALL
Select 3,'DC'
Select t.Num [Time],t.[State]
, CASE WHEN t.[state] = 'VA' THEN Count(t.[State]) ELSE 0 END [Number]
INTO #temp2
From temp t
Group by t.Num, t.[state]
--drop table #temp2
Select
t2.[time]
,SUM(t2.[Number])
From #temp2 t2
group by t2.[time]

Returning 1 or 0 in specific SQL query

I have three columns in the table MYTABLE (ID, NUM, NAMES). There is a column NAMES. I need to check on NAMES column to see if the first name is JACK or BRUCE and the corresponding NUM column = 0. If the match is found, return 1 else 0.
ID NUM NAMES
1 1 'TOM'
2 1 'MIKE'
3 0 'JACK'
4 1 'MICKY'
5 0 'BRUCE'
I've came up with the following query:
select *
case NAMES in ('JACK', 'BRUCE') and NUM=0 then 1 else 0 end as MYNAMES
from MYTABLE;
That does not work unfortunately.
This works (SQLFiddle demo):
SELECT id, num,
CASE WHEN names IN ('JACK', 'BRUCE') AND num=0
THEN 1 ELSE 0 END AS mynames
FROM mytable
select case
when exists
(
select *
from YourTable
where name in ('JACK', 'BRUCE')
and NUM = 0
)
then 1
else 0
end
from dual
Live example at SQL Fiddle.
select case when NAMES in ('JACK','BRUCE') AND NUM = 0
then 1
else 0
end
from your_table