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?
Related
I have table with data on old game characters. I'd like to add a gender column.
If I do
ALTER TABLE characters
ADD gender ENUM('m','f') AFTER char_name
then I get a column full of NULLs. How do I get the values in?
Using an INSERT statement tries to tag them all into new rows, instead of replacing the NULLs.
Using an UPDATE statement requires a new statement for every single entry.
Is there any way to just drop a "VALUES ('m'),('f'),('f'),('m'),('f') etc" into the ALTER statement or anything else and update them all efficiently?
There is no way to fill in specific values during ALTER TABLE. The value will be NULL or else a default value you define for the column.
You may find INSERT...ON DUPLICATE KEY UPDATE is a convenient way to fill in the values.
Example:
CREATE TABLE characters (
id serial primary key,
char_name TEXT NOT NULL
);
INSERT INTO characters (char_name) VALUES
('Harry'), ('Ron'), ('Hermione');
SELECT * FROM characters;
+----+-----------+
| id | char_name |
+----+-----------+
| 1 | Harry |
| 2 | Ron |
| 3 | Hermione |
+----+-----------+
Now we add the gender column. It will add the new column with NULLs.
ALTER TABLE characters
ADD gender ENUM('m','f') AFTER char_name;
SELECT * FROM characters;
+----+-----------+--------+
| id | char_name | gender |
+----+-----------+--------+
| 1 | Harry | NULL |
| 2 | Ron | NULL |
| 3 | Hermione | NULL |
+----+-----------+--------+
Now we update the rows:
INSERT INTO characters (id, char_name, gender) VALUES
(1, '', 'm'), (2, '', 'm'), (3, '', 'f')
ON DUPLICATE KEY UPDATE gender = VALUES(gender);
It looks strange to use '' for the char_name, but it will be ignored anyway, because we don't set it in the ON DUPLICATE KEY clause. The original char_name is preserved. Specifying the value in the INSERT is necessary only because the column is defined NOT NULL and has no DEFAULT value.
SELECT * FROM characters;
+----+-----------+--------+
| id | char_name | gender |
+----+-----------+--------+
| 1 | Harry | m |
| 2 | Ron | m |
| 3 | Hermione | f |
+----+-----------+--------+
DBFiddle
create table Branch
(
BranchNo char(4),
Street varchar(30),
City varchar(30),
PostCode varchar(10)
)
INSERT INTO BRANCH
VALUES ('B002', '55 cOVER', 'LONDON',NULL)
INSERT INTO BRANCH
VALUES ('B003', '163 Main Street', 'Glasgow',NULL)
INSERT INTO BRANCH
VALUES ('B004', '32 Manse Road', 'Bristol',NULL)
INSERT INTO BRANCH
VALUES ('B005', '22 Dear Road', 'LONDON',NULL)
INSERT INTO BRANCH
VALUES ('B007', '16 Argyll', 'Abend',NULL)
Create a view named ViewDeC that displays information of all branches. Must say
make sure it is not possible to update the data for the branch table (Branch) through this View
Create a view and don't let the database update mysql?
enter image description here
If I am not mistaken, this is about how to create a readonly view. Though MySQL does not support creating a view with readonly attribute DIRECTLY, certain things can be done to make the view READONLY. One workaround is to make the view through joined tables.
create view ViewDeC as
select BranchNo,Street,City,PostCode
from Branch
join (select 1) t;
select * from ViewDec;
INSERT INTO ViewDec
VALUES ('B009', '99 Argyll', 'bender',NULL);
-- Error Code: 1471. The target table ViewDec of the INSERT is not insertable-into
Note, this is implemented at the cost of some performance, but not terribly unbearable. I have a table with 1.4 million rows. Here is the test with and without join using a table scan as the access method.
select * from proctable;
-- 1429158 rows in set (1.26 sec)
select * from proctable join (select 1) t;
-- 1429158 rows in set (1.40 sec)
However, for an index lookup access method, this is almost non-existent.
select * from proctable join (select 1) t where id between 100 and 500;
-- 401 rows in set (0.00 sec)
explain select * from proctable join (select 1) t where id between 100 and 500;
+----+-------------+------------+------------+--------+---------------+---------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+--------+---------------+---------+---------+------+------+----------+----------------+
| 1 | PRIMARY | <derived2> | NULL | system | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| 1 | PRIMARY | proctable | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 401 | 100.00 | Using where |
| 2 | DERIVED | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+----+-------------+------------+------------+--------+---------------+---------+---------+------+------+----------+----------------+
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;
This seems like a simple question but I can't seem to find an answer. I have two tables. Table 1:
+---------+-----------+--------+-------+----------+
| userid | username | date | time | footsize |
+---------+-----------+--------+-------+----------+
| 1 | user1 | 103999 | 1010 | 9 |
| 2 | user2 | 484883 | 984 | 6 |
+---------+-----------+--------+-------+----------+
and Table 2:
+---------+-----------+----------+
| userid | natural | synthetic|
+---------+-----------+----------+
| 1 | y | n |
| 2 | n | y |
+---------+-----------+----------+
What I'd like to do is delete table 2.
But I need to move the columns and data natural and synthetic from table 2 and insert them into table 1, using userid as a primary key to make sure the data goes to the right customer.
I tried using the join statements but I can't seem to move them from joining to inserting without an error.
The general (loose) idea I want is
select userid from table1, select * from table2.
Insert into table1, table2.natural, table2.synthetic where table1.userid = table2.userid;
So that table 1 looks like this:
+---------+-----------+--------+-------+----------+-----------+----------+
| userid | username | date | time | footsize | natural | synthetic|
+---------+-----------+--------+-------+----------+-----------+----------+
| 1 | user1 | 103999 | 1010 | 9 | y | n |
| 2 | user2 | 484883 | 984 | 6 | n | y |
+---------+-----------+--------+-------+----------+-----------+----------+
I'm aware that's not a real query, but it should clarify what I'm trying to do. Thanks!
first you create a table that has all the columns
CREATE TABLE `table3` (
`userid` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NULL,
`date` INT NULL,
`time` INT NULL,
`footsize` INT NULL,
`natural` VARCHAR(45) NULL,
`synthetic` VARCHAR(45) NULL,
PRIMARY KEY (`userid`));
insert into table3
select t1.userid, t1.username, t1.`date`, t1.`time`, t1.footsize,
t2.natural, t2.synthetic
from table1 as t1
join table2 as t2
on t1.userid = t2.userid
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.