How to add a set of different values in one column(MySQL)? - 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;

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 omit mysql rows that match another table when neither is unique

I have two tables, one that holds potential items, the other holds completed items.
The potential item table currently contains the records that have also been added to the completed items table. I want to remove (either by deleting or selecting new results) the already completed items from the list of potential items.
In both tables, items may appear multiple times, and I only want to remove the number of items that are completed, not all that match.
The real data set is more larger of course, but here are samples.
Potential items:
mysql> select * from stack;
+----------+------+------+
| stack_id | type | name |
+----------+------+------+
| 3 | a | aa |
| 4 | b | bb |
| 5 | c | cc |
| 6 | d | dd |
| 7 | a | aa |
| 8 | b | bb |
+----------+------+------+
6 rows in set (0.00 sec)
Completed items
mysql> select * from temp;
+----------+------+------+
| item_id | type | name |
+----------+------+------+
| 1 | a | aa |
| 2 | b | bb |
| 6 | b | bb |
+----------+------+------+
3 rows in set (0.00 sec)
The IDs between tables do not correlate, so they should be ignored as far as finding matches.
I want to omit 1 instance of a/aa and 2 of b/bb since those have been completed and exist in the other table.
when I try this:
mysql> select stack.* from stack where (type,name) not in (select type,name from temp);
I get this:
+----------+------+------+
| stack_id | type | name |
+----------+------+------+
| 5 | c | cc |
| 6 | d | dd |
+----------+------+------+
2 rows in set (0.03 sec)
But this omitted both instances of type="a" and name="aa" and I want to only omit one of them (since it only exists once in the completed items table)
How do I get this?
+----------+------+------+
| stack_id | type | name |
+----------+------+------+
| 5 | c | cc |
| 6 | d | dd |
| 7 | a | aa |
+----------+------+------+
I don't care which instance of a/aa is deleted (whether id=7 or id=3)
The best I've been able to come up with is to use PHP rather than MySQL to loop through each record in temp and delete with a LIMIT 1 from stack.
But I'd rather not have to run code for this, I'd like to do it in queries, it works better that way in my workflow
Thanks!
CREATE TABLE `test`.`stack` (
`stack_id` INT UNSIGNED NOT NULL,
`type` VARCHAR(45) NULL,
`name` VARCHAR(45) NULL,
PRIMARY KEY (`stack_id`));
CREATE TABLE `test`.`temp` (
`item_id` INT UNSIGNED NOT NULL,
`type` VARCHAR(45) NULL,
`name` VARCHAR(45) NULL,
PRIMARY KEY (`item_id`));
and than something like this:
select
min(stack_id), type, name
from stack _s
inner join
(
select min(item_id) item_id, type, name
from temp
group by type, name
) _t using(type, name)
group by _s.type, _s.name
will give you only one the first item in temp:
stack_id
type
name
3
a
aa
4
b
bb

Copy id after insert to another table

I have two tables, but I would like to set a trigger. When I insert a new user to my table users, I would like to copy that id to another table: results.
Table users:
| userID | name | email | password |
+--------+----------+-------------------+----------+
| 1 | Person A | mailA#gmail.com | 12345 |
+--------+----------+-------------------+----------+
| 2 | Person B | mailB#yahoo.com | 13579 |
+--------+----------+-------------------+----------+
| 3 | Person C | mailC#outlook.com | 24681 |
+--------+----------+-------------------+----------+
Table results:
| resultID | userID | TestA | TestB |
+----------+--------+-------+-------+
| 162 | 1 | 84 | 63 |
+----------+--------+-------+-------+
| 028 | 2 | NULL | 54 |
+----------+--------+-------+-------+
| 821 | 3 | 77 | 60 |
+----------+--------+-------+-------+
I would like to copy the userID from table users to userID in table results after insert.
I tried various options with triggers, but nothing fixed my problems.
One of them is:
CREATE TRIGGER T_TableA_I
on users
after insert
as
set nocount on
insert into results (userID)
select u.UserID
from
users u
inner join
results r
on
u.UserID = r.UserID
It may be that my structure is not in accordance with the guidelines, but this is a concept.
I am still not sure if I understand the question but here's a code snippet for conversation
drop table if exists us,res;
create table us (id int);
create table res (id int);
drop trigger if exists t;
delimiter $$
create trigger t after insert on us
for each row
begin
insert into res(id) values (new.id);
end $$
delimiter ;
insert into us values (1);
select * from us;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
select * from res;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
I have written the following code snippet, but I could not figure out where to get the test result!
CREATE TABLE IF NOT EXISTS users (
userID INT(6) UNSIGNED PRIMARY KEY,
name VARCHAR(255),
password VARCHAR(255),
email VARCHAR(255)
);
CREATE TABLE IF NOT EXISTS results (
resultID INT(6) UNSIGNED PRIMARY KEY,
userID VARCHAR(255),
TestA VARCHAR(255),
TestB VARCHAR(255)
);
/* trigger query */
CREATE TRIGGER new_user_added
AFTER INSERT ON users
FOR EACH ROW
INSERT INTO results values('162', NEW.userID, '84', '63');
/* insert query */
replace into users values('1', 'Person A', 'mailA#gmail.com', '12345');
select * from users;
select * from results
users
| userID | name | email | password |
+--------+----------+-------------------+----------+
| 1 | Person A | mailA#gmail.com | 12345 |
+--------+----------+-------------------+----------+
results
| resultID | userID | TestA | TestB |
+----------+--------+-------+-------+
| 162 | 1 | 84 | 63 |
+----------+--------+-------+-------+
Hope this could help.

Insert a row and select or insert foreign key via a subquery

For the last two days I am stuck with the following problem I want to insert data in the logintime table with one query. I am running MySQL 5.7.21
The problem I face however: there is a possibility that the player doesn't exists in the player table, so therefor I am looking for a solution that looks up the foreign key and if it doesn't exists create a new player in the player table and use the newly created player id in the logintime table.
Player table:
+----+-------+------+
| id | name | type |
+----+-------+------+
| 1 | Steve | 2 |
| 2 | Tim | 1 |
+----+-------+------+
Logintime table:
+---------------------+------------+----------+
| logintime | logouttime | playerid |
+---------------------+------------+----------+
| 2018-02-04 12:44:11 | NULL | 1 |
| 2018-02-03 10:55:32 | NULL | 2 |
| 2018-02-03 09:22:02 | NULL | 1 |
+---------------------+------------+----------+
Thank you
EDIT
DELIMITER $$
CREATE PROCEDURE insertOnline (IN Name VARCHAR(30))
BEGIN
DECLARE playerid INT;
INSERT IGNORE INTO players (name) VALUES (Name);
SET playerid = (SELECT id FROM players p WHERE p.name = Name);
INSERT INTO playersonline (playerid) VALUES (playerid);
END$$
DELIMITER ;

Mysql Update SET data type values

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.