Mysql Update SET data type values - mysql

I have SET data type field in Mysql table, which contains values SET('dog','cat','hamster'). I would like to update value 'dog' into 'puppy' and as well change values in all records from 'dog' into 'puppy'. Thank you.

Use these three query's:
ALTER TABLE `table `CHANGE `field` `field` SET ('dog','cat','hamster', 'puppy' );
update table `table` set `field` ='puppy' where `field`='dog';
ALTER TABLE `table `CHANGE `field` `field` SET ('cat','hamster', 'puppy' );

The answer provided by Jens will work only when field has values 'dog' and nothing else. But this one is SET and not ENUM. Thus it can have field with multiple values which also includes 'dog'. For example - 'dog,cat', 'dog,hamster', 'dog,cat,hamster'. In such cases this answer won't work. Also here CHANGE is unnecessary and MODIFY will suffice. I have provided the code below which will work in any scenario -
CREATE TABLE my_table (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> animal SET("dog","cat","hamster"),
-> PRIMARY KEY (id)
-> );
INSERT INTO my_table (animal) VALUES ("dog");
INSERT INTO my_table (animal) VALUES ("dog,cat");
INSERT INTO my_table (animal) VALUES ("dog,hamster");
INSERT INTO my_table (animal) VALUES ("dog,cat,hamster");
SELECT * FROM my_table;
+----+-----------------+
| id | animal |
+----+-----------------+
| 1 | dog |
| 2 | dog,cat |
| 3 | dog,hamster |
| 4 | dog,cat,hamster |
+----+-----------------+
ALTER TABLE my_table
-> MODIFY animal SET (
-> "dog","cat","hamster","puppy");
DESCRIBE my_table;
+--------+------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------------------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| animal | set('dog','cat','hamster','puppy') | YES | | NULL | |
+--------+------------------------------------+------+-----+---------+----------------+
UPDATE my_table
-> set animal = CASE
-> WHEN animal LIKE "dog"
-> THEN REPLACE(animal,"dog","puppy")
-> WHEN animal LIKE "dog%"
-> THEN REPLACE(animal,"dog,","puppy,")
-> WHEN animal LIKE "%dog%"
-> THEN REPLACE(animal,",dog",",puppy")
-> ELSE animal
-> END;
SELECT * FROM my_table;
+----+-------------------+
| id | animal |
+----+-------------------+
| 1 | puppy |
| 2 | cat,puppy |
| 3 | hamster,puppy |
| 4 | cat,hamster,puppy |
+----+-------------------+
ALTER TABLE my_table
-> MODIFY animal SET("cat","hamster","puppy");
DESCRIBE my_table;
+--------+------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| animal | set('cat','hamster','puppy') | YES | | NULL | |
+--------+------------------------------+------+-----+---------+----------------+
The original credit goes to #Jens though.

Related

Using auto_increment id field value in other columns in the table

I am using mysql 8.0.30.
I have an orders table which is defined as follows:
create table orders (
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
code varchar (64) NOT NULL,
ord_num varchar(512) NOT NULL );
After inserting a rows, I would like to have it as follows:
+----+------+-------+
| id | code | ord_num|
+----+------+-------+
| 1 | abc | abc-1 |
| 2 | def | def-2 |
+----+------+-------+
That is ord_num should have concatenation of code-id. I can achieve that by an update statement as follows:
update orders set ord_num = concat (code, '-', id ) where id = 2;
However, I would like to achieve that in the insert statemenet. For ex:
insert into orders (code, ord_num) values ("xyz", concat(code, '-', id));
This actually results in:
+----+------+-----------+
| id | code | ord_num |
+----+------+-----------+
| 1 | abc | abc-0 |
| 2 | def | def-2 |
| 3 | xyz | xyz-0 |
+----+------+-----------+
I know I can do this by starting a transaction, insert with some dummy value in ord_num, then updating it with the correct value before committing. I would prefer to do it in one insert statement, if possible?

How to add a set of different values in one column(MySQL)?

Do not judge strictly, but I can not figure it out in any way
My table:
CREATE table courses (id INT PRIMARY KEY AUTO_INCREMENT,
-> faculty VARCHAR(55) NULL,
-> number INT(10) NULL,
-> diff VARCHAR(10) NULL);
mysql> select * from courses;
Target. Inject values ('ez', 'mid', 'hard') into diff column.
For exampl, im trying this:
mysql> INSERT courses (diff) VALUES ('ez');
OR
mysql> UPDATE courses SET faculty = 'chem', number = 2, diff = 'mid';
Add rows with empty id(values NULL).
PLZ help me!
I want to get this result
+----+---------+--------+------+
| id | faculty | number | diff |
+----+---------+--------+------+
| 1 | bio | 1 | ez |
| 2 | chem | 2 | mid |
| 3 | math | 3 | hard |
| 4 | geo | 4 | mid |
| 5 | gum | 5 | ez |
+----+---------+--------+------+
You can use a case expression in an UPDATE statements:
UPDATE courses
SET diff=CASE
WHEN faculty in ('bio', 'gum') THEN 'ez'
WHEN faculty in ('chem', 'geo') THEN 'mid'
WHEN faculty = 'math' THEN 'hard'
END;

What is wrong in this Update query which tried to update table using concat() fun

I want to update the field with appending data into it, but it is giving an error, please correct me (Query and Table desc are below)
I tried to fire UPDATE command with CONCAT () FUNCTION in SQL.
update products a
set a.des = (select concat((select b.des from products b limit 1) ,' one okay') from a)
where a.p_id = 1;
I have used MySQL,
Table Description:
mysql> desc products;
+---------+-------------+------+-----+--------------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+--------------+-------+
| p_id | int(3) | NO | PRI | 0 | |
| p_name | varchar(10) | YES | | NULL | |
| p_price | int(10) | YES | | NULL | |
| cat_id | int(3) | YES | MUL | NULL | |
| des | varchar(30) | YES | | Good | |
+---------+-------------+------+-----+--------------+-------+
Expected Output :
mysql> select * from products;
+------+--------+---------+--------+---------------+
| p_id | p_name | p_price | cat_id | des |
+------+--------+---------+--------+---------------+
| 1 | Mouse | 150 | 3 | Good one okay |
| 2 | LAN | 50 | 4 | Good |
+------+--------+---------+--------+---------------+
2 rows in set (0.00 sec)
Output Came :
Error -
update products a set a.des =
(select concat((select b.des from products b limit 1) ,' one okay')
from a) where a.p_id = 1 Error Code: 1146. Table 'test.a' doesn't exist 0.437 sec
MySQL does not allow you to reference the table being updated in the rest of the update statement, as a general rule.
The normal work-around is to phrase this as a JOIN:
update products p cross join
(select * from products limit 1) arbitrary
set p.des = concat(arbitrary.des, ' one okay')
where p.p_id = 1;
Note the use of the alias arbitrary. You are using limit with no order by so you are getting an arbitrary description.
If you just want to append a string to the existing description, then you want the simpler:
update products p
set p.des = concat(p.des, ' one okay')
where p.p_id = 1;

What happens when I select a varchar column using number type?

I have a table:
CREATE TABLE `test` (
`t` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
The data in the table is:
mysql> select * from test;
+----------------------+
| t |
+----------------------+
| 12511023900355495873 |
| 12511023900355495872 |
| 12511023900355495874 |
+----------------------+
When I select from the table like this:
select * from test where t = 12511023900355495873;
The result is:
+----------------------+
| t |
+----------------------+
| 12511023900355495873 |
| 12511023900355495872 |
| 12511023900355495874 |
+----------------------+
What implicit conversion happens when I use number to select a varchar column?
The manual page https://dev.mysql.com/doc/refman/5.7/en/type-conversion.html In all other cases, the arguments are compared as floating-point (real) numbers.
so
drop table if exists t;
CREATE TABLE t (
t varchar(255) DEFAULT NULL,
t1 float
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into t values
( 12511023900355495873,12511023900355495873 ),
( 12511023900355495872,12511023900355495872 ),
( 12511023900355495874,12511023900355495874 );
select t.*,#t2 from t where t = 12511023900355495873;
results in
+----------------------+-----------+------+
| t | t1 | #t2 |
+----------------------+-----------+------+
| 12511023900355495873 | 1.2511e19 | NULL |
| 12511023900355495872 | 1.2511e19 | NULL |
| 12511023900355495874 | 1.2511e19 | NULL |
+----------------------+-----------+------+
3 rows in set (0.00 sec)
Note that all float values in the column t1 are the same.
It goes without saying that you should avoid type conversion.

Upsert - Update if exists else Insert in MySQL

I'm looking for a simple upsert (Update/Insert). The tables looks like this
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| email | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
There is no key here. The idea is to insert if email is different, else update. The Insert on duplicate key in mysql doesn't suit the purpose.
Is there an elegant way to do this?
If you cannot add a unique key on the email column, you'll check to see if the record exists first (preferably in a transaction):
SELECT id FROM mytable WHERE email = 'my#example.com' FOR UPDATE
then update the record if it exists:
UPDATE mytable SET name = 'my name' WHERE id = ?
otherwise insert it:
INSERT INTO mytable (name, email) VALUES ('my name', 'my#example.com')
what about:
REPLACE INTO table VALUES(1,'hello', 'world#example.com');