Insert multiple rows, most of them constant - mysql

I have to insert big amount of records in a table. It is not quite normalized, so most of the fields are repeated.
I know the proper command is:
INSERT INTO table_name (field1, field2, ..., field_n)
VALUES (value1, value2, ..., value_n),
...
(value1, value2, ..., value_n)
But I wonder whether it is possible to keep some of the values fixed and just indicate the different ones.
Let's say instead of
INSERT INTO table_name (shop, month, sale)
VALUES (1, 2, 23),
(1, 2, 28),
(1, 2, 29),
(1, 2, 30)
Having something like
INSERT INTO table_name (shop, month, sale)
VALUES (1, 2, 23), ... 28 / 29 / 30
If it is not possible I would create a procedure with a loop, feeding a string, etc. It would not be a big issue, but my point is to know if INSERT INTO has any particularity that allows doing this without procedures.

You can try something like the following:
INSERT INTO table_name (shop, month, sale)
SELECT * FROM
(SELECT 1 as shop, 2 as month) as sm,
(SELECT 23 as sale UNION ALL SELECT 28 UNION ALL SELECT 30) as sales;

You can use the default constraint which will add the default value when you do not specify that in the insert into statement. If you specify a value that value will be added.
Just set the default value for your column in your table
ALTER TABLE tblname ALTER columnName SET DEFAULT 'value'
Refer http://www.w3schools.com/sql/sql_default.asp

You can use a temporary table to insert the different values and then use insert ... select. I don't know if it will be a big saving for you:
CREATE TEMPORARY TABLE sale_temp (sale int);
INSERT sale_temp (sale) VALUES (23), (28), (29), (30);
INSERT INTO table_name (shop, month, sale)
SELECT 1, 2, sale
FROM sale_temp;
DROP TABLE sale_temp;

Related

Is there any way to order result by column value?

I have MySQL table with many columns.
id|Date |col1|col2|col3|col4|col5|... |col500|
-----------------------------------------------------------------
1|01.10.2019| 152| 99| 0|1598| 48| filled with zeros| 1|
-----------------------------------------------------------------
2|02.10.2019| 12| 344| 19|2544| 3| filled with zeros| 152|
-----------------------------------------------------------------
....
Is it possible to order column
SELECT * FROM table WHERE Date = '02.10.2019' ORDER BY COLUMNS
and get result like this
id|Date |col4|col2|col500|col3|col1|col5|... |
-----------------------------------------------------------------
2|02.10.2019 |2544| 344| 152| 19| 12| 3|filled with zeros
If you want to order by columns value, as Madhur Bhaiya and P.Salmon said, may be your table is not properly designed, and you are probably speaking of rows, and not of columns.
Instead of a table with columns ID/ Date/ col1/ col2/ ... / col500, perhaps you need a table like this
CREATE TABLE tbl(
pk integer not null primary key default autoincrement,
id integer not null,
dt date not null,
xxx_id integer,
value integer);
where XXX_ID represent the column position in your old table (may be an identifier of single record, I don't know what you are using this table for).
Now you have to insert the values:
INSERT INTO tbl (id, date, value) VALUES (1, '2019-10-01', 152);
INSERT INTO tbl (id, date, value) VALUES (1, '2019-10-01', 99);
INSERT INTO tbl (id, date, value) VALUES (1, '2019-10-01', 0);
INSERT INTO tbl (id, date, value) VALUES (1, '2019-10-01', 1592);
INSERT INTO tbl (id, date, value) VALUES (1, '2019-10-01', 48);
....
INSERT INTO tbl (id, date, value) VALUES (2, '2019-10-02', 12);
INSERT INTO tbl (id, date, value) VALUES (2, '2019-10-02', 344);
INSERT INTO tbl (id, date, value) VALUES (2, '2019-10-02', 19);
INSERT INTO tbl (id, date, value) VALUES (2, '2019-10-02', 2544);
...
And the answer to your question becomes very easy, something like
select * from tbl
where id = 1 AND date = '2019-10-01'
order by value
Last point: you can decide to insert records with ZERO value, or skip them, or insert them with NULL value. It depends on what is the goal of the table.

MySQL: Inserting row with default values

I have a table with something like 100 columns and now I would like to insert a row with some columns equal to some values and default values for all other columns. Is it possible?
Something like:
insert into tablename (col1, col22, col33) values (1, 2, 3)
The columns not listed in the column list will be assigned to their default values.
You can also do:
insert into tablename values (1, default, 3, default, 5, ..., 100)
But nothing I'd do with 100 columns. Too easy to make mistakes.

Insertion in Mysql, where one column has a constant value

I have a table with 2 column say C1 and C2. i need to insert 10 rows where always Columns 2 will be same.
INSERT INTO Table
(C1, C2)
VALUES
(100, 'X'),
(101, 'X'),
(102, 'X'),
(103, 'X'),
(104, 'X'),
(105, 'X'),
(106, 'X');
Is there any other way like below,
INSERT INTO Table
(C1)
VALUES
(100,102,103,104,105,106)
and value of C2 should be X for the inserted rows
Thanks in advance,
You will have to create a table
CREATE TABLE `tblA` (
`C1` INT(10) NULL,
`C2` VARCHAR(50) NULL DEFAULT 'X'
);
Then when you do INSERT INTO Table (C1) VALUES (100,102,103,104,105,106); the column C2 will have 'X' as a value.
There are, but not really very advantageous, one way or the other. If what you're trying to do is to write the constant value only once, I'd try to keep it simple and go for
SET #X := 'X'
or
SELECT #X := expression FROM ...
followed by
INSERT INTO Table
(C1, C2)
VALUES
(100, #X), (102, #X), ...;
You can apply an insert into from a select statement VALUES is hard-coded answers... insert into from select is query based insert. In the sample below, I am using #MySQL variables to create a variable "#num" and start it at 99. Then you just have to substitute per the sample as it describes... Any table that has at least the number of records you want to add. So, in my case, I am only concerned with any table that has AT LEAST 10 records. If you want to add 1000, and have a table with AT LEAST that many records, use that. The LIMIT obviously limits how many records you return from it. Since you are not really using any columns from the table, it doesn't matter what that table is. So, now the #num := #num +1 will keep increasing for every record processed, thus going to 100, 101, 102, etc for the "c1" column, and the 'X' will be constanct for the "c2" column and you are done.
INSERT INTO Table
(C1, C2)
select
#num := #num +1 as c1,
'X' as c2
from
AnyTableThatHasAtLeastNumberOfRecordsYouWant,
( select #num := 99 ) sqlvars
limit
10

SQL Insert Into a MAX value

In SQL how would I insert into a MAX count of another column
So I have this
INSERT INTO USER(id,name,employee_code,email) VALUES (3,john,(SELECT MAX(employee_code)+1 FROM USER),"john#example.com");
However this doesn't work with the syntax... basically it's like an autoincrement that I have to self build because the employee_code sometimes equals 0 for temporary employees so I need a command to take the max code in their and add one.
You probably forgot quotes around john:
INSERT INTO USER(id,name,employee_code,email)
VALUES (3, 'john', (SELECT MAX(employee_code)+1 FROM `USER`), "john#example.com");
Do away with the VALUES statement and use a select instead:
INSERT INTO USER(id,name,employee_code,email)
SELECT 3, 'john', MAX(employee_code)+1, "john#example.com"
FROM USER
You need to use an INSERT INTO... SELECT ...FROM query:
INSERT INTO USER(id,name,employee_code,email)
SELECT 3, 'john', MAX(employee_code)+1, 'john#example.com'
FROM `USER`;
INSERT INTO USER(id,name,employee_code,email)
SELECT
3,
'john',
MAX(employee_code)+1,
'john#example.com'
FROM USER

Insert record into table with position without updating all the records position field

I am using MySQL, I don't have a good way to do this.
I have a table with a position field, which I need to keep track having values from 1 to 10,000.
Let's say I insert a record in the middle at 5000th position. So position 5000 to 10,000 need to be updated to the new position; old 5000 become 5001, 5002 becomes 5003...
Is there a good way to implement this without affecting so many records, when 1 single position is added?
Adding from the position 1st is the worst.
I'd rethink the database design. If you're going to be limited to on the order of 10K records then it's not too bad, but if this is going to increase without bound then you'll want to do something else. I'm not sure what you are doing but if you want a simple ordering (assuming you're not doing a lot of traversal) then you can have a prev_id and next_id column to indicate sibling relationships. Here's the answer to your questions though:
update some_table
set some_position = some_position + 1
where some_position > 5000 and some_position < 10000
You can try the below approach :
USE tempdb;
GO
CREATE TABLE dbo.Test
(
ID int primary key clustered identity(1,1) ,
OrderNo int,
CreatedDate datetime
);
--Insert values for testing the approach
INSERT INTO dbo.Test
VALUES
(1, GETUTCDATE()),
(2, GETUTCDATE()),
(3, GETUTCDATE()),
(4, GETUTCDATE()),
(5, GETUTCDATE()),
(6, GETUTCDATE());
SELECT *
FROM dbo.Test;
INSERT INTO dbo.Test
VALUES
(3, GETUTCDATE()),
(3, GETUTCDATE());
SELECT *
FROM dbo.Test;
--To accomplish correct order using ROW_NUMBER()
SELECT ID,
OrderNo,
CreatedDate,
ROW_NUMBER() OVER(ORDER BY OrderNo, ID) AS Rno
FROM dbo.Test;
--Again ordering change
INSERT INTO dbo.Test
VALUES
(3, GETUTCDATE()),
(4, GETUTCDATE());
SELECT ID,
OrderNo,
CreatedDate,
ROW_NUMBER() OVER(ORDER BY OrderNo, ID) AS Rno
FROM dbo.Test
DROP TABLE dbo.Test;