i have table named chat_users with columns:
id | username | status | time_mod | views
Here is an example of UPDATE with CASE statement that works brilliantly:
$db->exec("UPDATE `proba13`.`chat_users`
SET `username` = CASE id
WHEN 4 THEN 'Jie'
WHEN 5 THEN 'Mie'
WHEN 6 THEN 'Pres'
END,
`status` = CASE id
WHEN 4 THEN '1'
WHEN 5 THEN '2'
WHEN 6 THEN '3'
END
WHERE id IN (4,5,6)");
QUESTION:
can anybody please give me an example of SELECT with CASE statement on the same table ?
regards and
Thank you in advance!
This will return the same results as your updated table (however, obviously without making any changes to it):
SELECT id,
CASE id
WHEN 4 THEN 'Jie'
WHEN 5 THEN 'Mie'
WHEN 6 THEN 'Pres'
ELSE username
END AS username,
CASE id
WHEN 4 THEN 1
WHEN 5 THEN 2
WHEN 6 THEN 3
ELSE status
END AS status,
time_mod,
views
FROM proba13.chat_users
Try this one
SELECT (CASE WHEN
id =4 THEN 'Jie'
WHEN id =5 THEN 'Mie'
WHEN id =6 THEN 'Pres'
END ) `username` ,
(CASE WHEN
id= 4 THEN '1'
WHEN id= 5 THEN '2'
WHEN id= 6 THEN '3'
END ) `status` FROM `chat_users`
WHERE id IN (4,5,6)
Related
I have 2 tables
orders
order_id
1
2
3
orders_details
order_id
sku
ordered
received
1
abc
10
10
1
xyz
10
10
2
abc
10
6
2
xyz
10
0
3
abc
10
0
4
xyz
10
0
I would like to add to the orders table a column called status which would have the results 'complete', 'partial' and 'open' based on what has been received in the orders_details table
result I am trying to acheive
order_id
status
1
complete
2
partial
3
open
The problem is when a different product from the same order_id has a different received result it creates an additional row with the group by.
result I am getting
order_id
status
1
complete
2
open
2
partial
3
open
https://www.db-fiddle.com/f/bFrYguhmcMJ32iFuUcXfDw/3
SELECT
`orders`.`order_id`,
(CASE
WHEN `received` >= `ordered` THEN 'complete'
WHEN `received` < `ordered` AND `received` != 0 THEN 'partial'
WHEN `received` = 0 THEN 'open'
END) AS `status`
FROM
`orders`
LEFT JOIN `orders_details` ON `orders_details`.`order_id` = `orders`.`order_id`
GROUP BY
`order_id`, `status`
;
I might be missing something, but I think you just want:
SELECT `orders`.`order_id`,
CASE SUM(received)
WHEN 0 THEN 'open'
WHEN SUM(ordered) THEN 'complete'
ELSE 'partial'
END AS `status`
FROM `orders`
LEFT JOIN `orders_details`
ON `orders_details`.`order_id` = `orders`.`order_id`
GROUP BY `order_id`;
Here's your updated DB Fiddle
It is a bit hacky, but you can define the order by giving then names of the status an order the should be choosen, and then take the maximum for this order.
Zcomplete>partial>open
We can thenremove the additional charatcers
Query #1
SELECT
`orders`.`order_id`,
REPLACE (MAX((CASE
WHEN `received` >= `ordered` THEN 'Zcomplete'
WHEN `received` < `ordered` AND `received` != 0 THEN 'partial'
WHEN `received` = 0 THEN 'open'
END)), 'Z', '') AS `status`
FROM
`orders`
LEFT JOIN `orders_details` ON `orders_details`.`order_id` = `orders`.`order_id`
GROUP BY
`order_id`
;
order_id
status
1
complete
2
partial
3
open
View on DB Fiddle
I have a table called associate_ratings with the below structure:
id int(11) NO PRI auto_increment
associate varchar(10) NO
skill_id int(11) NO MUL
rating int(11) NO
updated_time datetime NO
This table holds the skills(skill_id) of the associate and their corresponding rating in that skill.
Rating column can take values (1,2,3)
I want to get the in each skill how many associates have got a particular rating, please find below output table structure:
Skill_id Rating1_count Rating2_count Rating3_count
Java 2 1 4
C# 3 2 2
This says in Java there are 2 associates with rating 1, 1 associates with rating 2 & 4 associates with rating 3
I tried the below query, but the output is not in the format I expect:
SELECT skill_id, rating, count(*) FROM associate_ratings a
WHERE updated_time = (
SELECT max(updated_time)
FROM skill_set.associate_ratings b
WHERE a.associate = b.associate
) GROUP BY a.skill_id, a.rating order by a.skill_id, a.rating;
Could you please let me know how to get the output in the format I want?
Use temporary table and case
SELECT skill_id, sum(rating_1), sum(rating_2), sum(rating_3)
FROM (
SELECT a.skill_id as skill_id,
case a.rating when '1' then 1 else 0 end as rating_1,
case a.rating when '2' then 1 else 0 end as rating_2,
case a.rating when '3' then 1 else 0 end as rating_3
FROM associate_ratings a
WHERE updated_time = (
SELECT max(updated_time)
FROM skill_set.associate_ratings b
WHERE a.associate = b.associate
) ) as t
GROUP BY skill_id
ORDER BY skill_id;
select Skill_id ,
count(case when rating = 1 then 1 else null end) as Rating1_count ,
count(case when rating = 2 then 1 else null end) as Rating2_count ,
count(case when rating = 3 then 1 else null end) as Rating3_count
from associate_ratings b
left join associate_ratings a
on b.Skill_id = a.Skill_id
group by Skill_id
That would be something like this:
SELECT
skill_id,
sum(IF(rating=1,1,0)) as Rating1_count,
sum(IF(rating=2,1,0)) as Rating2_count,
sum(IF(rating=3,1,0)) as Rating3_count
FROM associate_ratings
GROUP BY skill_id
ORDER BY skill_id;
I think it's the most simple solution possible here.
I don't know how to title this Q.
I got a table in my DB that's looking like this:
[id][name][type]
1-John-2
2-Jack-3
3-Liam-1
4-Kim-1
5-Michael-3
And many more
I would like to make a list where it's grouped by type,
but where type 1 and 2 is one group, like this:
[Type 1 and 2]
1 - John
3 - Liam
4 - Kim
[Type 3]
2 - Jack
Is it possible to group like that in MySQL?
Yes you can use case
select *,
case when `type` =2 then 1 else `type` end new_type
from t
order by `type` ;
With aggregate fucntions
select count(*)
,case when `type` =2 then 1 else `type` end new_type
from t
group by new_type
Demo
I'm new to MySQL.
I'm using this to update multiple rows with different values, in a single query:
UPDATE categories
SET order = CASE id
WHEN 1 THEN 3
WHEN 2 THEN 4
WHEN 3 THEN 5
END,
title = CASE id
WHEN 1 THEN 'New Title 1'
WHEN 2 THEN 'New Title 2'
WHEN 3 THEN 'New Title 3'
END
WHERE id IN (1,2,3)
I am using "WHERE" to improve performance (without it every row in the table would be tested).
But what if I have this senario (when I don't want to update title for id 2 and 3):
UPDATE categories
SET order = CASE id
WHEN 1 THEN 3
WHEN 2 THEN 4
WHEN 3 THEN 5
END,
title = CASE id
WHEN 1 THEN 'New Title 1'
END
WHERE id IN (1,2,3)
The above code will change the title for id 2 and 3 into "NULL"...
What is the right way to make the query, but skip updating title for id 2 and 3 and still keep the performance "WHERE id IN" gives ?
Maybe like this
UPDATE categories
SET order = CASE id
WHEN 1 THEN 3
WHEN 2 THEN 4
WHEN 3 THEN 5
END,
title = CASE id
WHEN 1 THEN 'New Title 1'
WHEN THEN
WHEN THEN
END
WHERE id IN (1,2,3)
Set title equal to itself when you don't want to update it to a different value.
UPDATE categories
SET order = CASE id
WHEN 1 THEN 3
WHEN 2 THEN 4
WHEN 3 THEN 5
END,
title = CASE id
WHEN 1 THEN 'New Title 1'
ELSE title
END
WHERE id IN (1,2,3)
UPDATE `table_name` SET `field_name1` = CASE `id`
WHEN '1' THEN 'value_1'
WHEN '2' THEN 'value_2'
WHEN '3' THEN 'value_3'
ELSE `field_name1`
END,
`field_name2`= CASE id
WHEN '1' THEN 'value_1'
WHEN '2' THEN 'value_2'
WHEN '3' THEN 'value_3'
ELSE `field_name2`
END
I'm looking to create a sql statement that will update a large set of data.
What I have is a table like
id, transid, amount, narative1, narative 2, total, active
1 1234 23.2 NULL NULL NULL 1
2 1234 120.33 NULL NULL NULL 1
3 1235 98.00 NULL NULL NULL 1
When there are two rows with the same transid I need to total them put the result in the total column of the first one with that transid and put the second amount in naritive2 of the first instance as well as make the second one inactive. It should ignore single rows for a transid.
The result of what I want to do should be:
id, transid, amount, narative1, narative 2, total, active
1 1234 23.2 NULL 120.33 143.53 1
2 1234 120.33 NULL NULL NULL 0
3 1235 98.00 NULL NULL NULL 1
I know a bit of a thong twister but..
Ideally I'd like to do this in just a MySQL statements. So I don't mind having to do multiple sql statements but I want to avoid connecting it to PHP etc. Its a very large set of data.
This will update only those transactions that have exactly 2 rows (not 1 and not 3 or more).
UPDATE mytable mtu
JOIN (
SELECT minid, maxid, mtmin.amount AS minamt, mtmax.amount AS maxamt
FROM (
SELECT MIN(id) AS minid, MAX(id) AS maxid
FROM mytable mti
GROUP BY
transid
HAVING COUNT(*) = 2
) mt
JOIN mytable mtmin
ON mtmin.id = minid
JOIN mytable mtmax
ON mtmax.id = maxid
) mts
ON id IN (minid, maxid)
SET narative2 = CASE id WHEN minid THEN minamt ELSE NULL END,
total = CASE id WHEN minid THEN minamt + maxamt ELSE NULL END,
active = (id = minid)