MySQL Inserting data from other tables - auto increment skips - mysql

I have an empty "new_table" and "old_1" + "old_2" tables.
When I insert 3000 rows from old_1 to new_table everything is fine.
But when I insert data from old_2 table, auto_increment id's starts from ~4000, not from 3000.. Any ideas why this is happening? I would like to have the new rows starting from 3001.
INSERT INTO new_table ( col1,col2,col3 ) SELECT col1,col2,col3 FROM old_1;
INSERT INTO new_table ( col1,col2,col3 ) SELECT col1,col2,col3 FROM old_2;
EDIT: I havent deleted any rows or messed with auto_increment values at all. I just ran 2 queries in a row

Related

Insert into multiple tables only if record doesn't exist in primary table

I don't seem to understand IF statements in SQL very well.
I have two tables, one called event_headers and one called event_records. Each event in has a single entry in the event_header table and at least one record in the event_records table.
I'm running a script in c# that reads SQL files that will insert into each table, but I'm running into a problem with duplicates. I can eliminate the duplicates in the event_header table by using INSERT IGNORE. The trouble I have is I want to be able to skip inserting into the event_records table if there is already an entry in the event_header table.
EXAMPLE:
INSERT INTO `event_headers` (`session_id`, [...] ) VALUES ('89131', [...] );
INSERT INTO `event_records` (`event_header_session_id`, [...] )
VALUES
('89131', [...] ),
('89131', [...] ),
('89191', [...] );
(In truth, I have a third table that also has records that get updated, but this illustrates the point).
I want to only run the INSERT statements if the event_headers.session_id does not exist.
You must check does the 1st insertion inserts the row. You may do this, for example, using ROW_COUNT() which returns the amount of rows really altered in previous statement. The only point - you must use INSERT .. SELECT for 2nd insertion because INSERT .. VALUES does not allow WHERE clause:
INSERT IGNORE INTO main_table VALUES (...);
INSERT INTO slave_table
SELECT *
FROM ( SELECT ... UNION ALL SELECT ... ) slave_data;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=0668b71ddcdc67180b3ed54acb562931
Both statements must be executed as a batch (in the same connection, without any other statement between them).
Only one row must be inserted into main table.
But stored procedure which checks the presence in main table and inserts only when no such row is preferred.
Instead of just using VALUES, use a select:
INSERT INTO `event_records` (`event_header_session_id`, col_a, col_b, col_c )
SELECT event_header_session_id, col_a, col_b, col_c
FROM (
SELECT NULL event_header_session_id, NULL col_a, NULL col_b, NULL col_c WHERE 0
UNION ALL
VALUES
ROW('89131', 1,2,3 ),
ROW('89131', 2,3,4 ),
ROW('89191', 3,4,5 );
) new_rows
WHERE NOT EXISTS (
SELECT 1
FROM event_headers
WHERE event_headers.session_id=new_rows.event_headers_session_id
);
The SELECT NULL...UNION ALL is the most portable way I know to name the columns of a VALUES table constructor. On mariadb, omit the ROWs.

Inserting Non duplicate data into a table from Parent table

I have 2 tables : OSUSR_1SV_STAGING_FTP and #OSUSR_1SV_STAGING_FTP1
with same columns on both the table as :
Customer_Part_Number,
Lear_Part_Number,
Shipping_ID,
Customer_Name,
Effective_Date,
End_Date,Change_ID,
PO_Number,
PO_Price
I have successfully copied all the data to table #OSUSR_1SV_STAGING_FTP1 from table OSUSR_1SV_STAGING_FTP.
But my scenario stucks when the records are same in table OSUSR_1SV_STAGING_FTP and I don't want it to get it inserted to table #OSUSR_1SV_STAGING_FTP1.
Just need to insert non duplicate records.
This inserts records only which are in OSUSR_1SV_STAGING_FTP but not in OSUSR_1SV_STAGING_FTP1
INSERT INTO OSUSR_1SV_STAGING_FTP1
SELECT * FROM OSUSR_1SV_STAGING_FTP
EXCEPT
SELECT * FROM OSUSR_1SV_STAGING_FTP1
First off you need to have a unique id for each row. Then you can select from Table 1 (OSUSR_1SV_STAGING_FTP) and insert into Table 2 (#OSUSR_1SV_STAGING_FTP1) where it doesn't already exist.
INSERT INTO #OSUSR_1SV_STAGING_FTP1
SELECT *
FROM OSUSR_1SV_STAGING_FTP
WHERE OSUSR_1SV_STAGING_FTP.[Unique_ID] NOT IN
(SELECT Unique_ID FROM #OSUSR_1SV_STAGING_FTP1)
Noel

SQL Insert from table to table prevented by duplicate primary key from source table

I am trying to populate a products table on MySQL with latest products, which are retrieved and stored in products_temp table.
So the method for this is straight forward, simply doing an INSERT to products from products_temp, as such:
INSERT INTO products ( select products_temp.* FROM products_temp )
Problem is, it results in a duplicate primary key error, because of the id from products_temp clashing with the id in products.
Can someone tell me how to fix this please?
I tried declaring the fields in the select statement without the id, but that results in "Column count doesn't match value count at row 1"
Any help would be appreciated.
Thanks!
You'll need to declare the columns except the ID on both the INSERT and the SELECT, since the number of fields need to match, and id (as you noticed) can't be inserted as is into the destination table.
INSERT INTO DestTable (field1, field2, field3)
SELECT field1, field2, field3 FROM SourceTable;
An SQLfiddle to test with.
EDIT: You could do it in a bit more hacky way to simplify the insert. You can create a trigger that simply forces the primary key to NULL on insert.
CREATE TRIGGER t_DT BEFORE INSERT ON DestTable
FOR EACH ROW
SET NEW.id = NULL;
then a copy from table to table can be done as simply;
INSERT INTO DestTable SELECT * FROM SourceTable;
Another SQLfiddle.
How about something like:
INSERT INTO products
(
select products_temp.* FROM products_temp
where key not in (select key from products)
)

Creating a table on the basis of a field

I have a MySql table which has about 100k rows. there is one field say id which contains numbers from 1-35. all these records fall in this range of id i.e. all these records have value of id column between 1-35.
Now i want to create another table which will have one row of each id. i.e the new table should have 35 rows only.
How to go about it ?
create table new_table (id int);
insert into new_table
select distinct id from big_table;
Edit:
You can create the new_table by outputting the big_table create script and changing the name.
SHOW CREATE TABLE big_table;
/* modify the name of the output and execute */
insert into new_table
select * from big_table group by id
You have a table with 100.000 rows, and you want a new table with 35 rows. What values do you want for the remaining columns?
If the answer is: doesn't matter, this works:
CREATE TABLE newTable
SELECT * FROM yourTable
GROUP BY ID;
If you only want the IDs,
CREATE TABLE newTable
SELECT DISTINCT ID FROM yourTable;
You can copy data from one table to another even difference database(Schema) as following
INSERT INTO [DestDatabase].[DestTablName]
SELECT [ColumnName] FROM [SourceDatabase].[SourceTablName];
So, you can use two way:
1:
INSERT INTO tbl_New
SELECT DISTINCT id from tbl_Original;
2:
INSERT INTO tbl_New
SELECT id from tbl_Original GROUP BY id;

Execute INSERT if table is empty?

Is there a way to do an insert under a count condition, something like:
INSERT INTO my_table (colname) VALUES('foo') IF COUNT(my_table) < 1
Basically I want to insert a single default record if the table is currently empty. I'm using mysql.
Use SELECT instead of VALUES to be able to expand the query with a WHERE clause.
EXISTS is a better & faster test than COUNT
INSERT INTO my_table (colname)
SELECT 'foo'
WHERE NOT EXISTS (SELECT * FROM my_table)
One way would be to place a unique key on a column. Then execute a REPLACE:
REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name [(col_name,...)]
{VALUES | VALUE} ({expr | DEFAULT},...),(...),...
REPLACE works exactly like INSERT,
except that if an old row in the table
has the same value as a new row for a
PRIMARY KEY or a UNIQUE index, the old
row is deleted before the new row is
inserted
This is easier to read:
INSERT INTO my_table (colname)
SELECT 'foo' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM my_table);
The lack of a VALUES is mitigated by the SELECT FROM DUAL which will provide the values. the FROM DUAL is not always required, but it doesn't hurt to include it for that weird configurations where it is required (like the installation of Percona I am using).
The NOT EXISTS is faster than doing a count which can be slow on a table with a large number of rows.