MYSQL - Upsert from one table to another - mysql

I am trying to use upsert to update and or insert from another table
INSERT INTO table1 (
`uniqueCol1`,
`uniqueCol2`,
`created`,
`dataCol`
)
VALUES (
1,
t1.uniqueCol2Value,
NOW(),
t1.dataColValue
)
ON DUPLICATE KEY UPDATE
`dataCol` = t1.dataColValue
Now from what I can tell I don't see how I can add what I think should be FROM table2 t1 into this to grab the values and put them into table1

I would suggest:
INSERT INTO table1 (
`uniqueCol1`,
`uniqueCol2`,
`created`,
`dataCol`
)
SELECT 1, uniqueCol2Value, NOW(), dataColValue FROM table2

Related

INSERT SELECT using a UNION statement in the WHERE condition

I have a query that goes something like this :
INSERT IGNORE INTO `destination_table` (`id`, `field1`, `field2`, `field3`)
SELECT `id`, `field1`, `field2`, `field3`
FROM `source_table`
WHERE `source_table`.`id` IN (
SELECT DISTINCT `id` FROM `some_table`
UNION DISTICT SELECT DISTINCT `id` FROM `some_other_table`
);
This does not work -- the query hangs indefinitely. The size of the tables is definitely not the problem, all tables have a fairly small number of records ( < 100k records). The query is fine and quite fast if I run it without the UNION :
INSERT IGNORE INTO `destination_table` (`id`, `field1`, `field2`, `field3`)
SELECT `id`, `field1`, `field2`, `field3`
FROM `source_table`
WHERE `source_table`.`id` IN (
SELECT DISTINCT `id` FROM `some_table` -- I tried with `some_other_table` too, same result
);
or
INSERT IGNORE INTO `destination_table` (`id`, `field1`, `field2`, `field3`)
SELECT `id`, `field1`, `field2`, `field3`
FROM `source_table`
both work and are nice and fast (well under a second). So I imagine that the UNION DISTICT SELECT ... is the culprit here, but I don't know why.
What's wrong with that query and why does it hang ?
Using mysql 5.7 is that makes a difference
Your first query seems to have a few typos, but I would suggest using exists logic here:
INSERT IGNORE INTO destination_table (id, field1, field2, field3)
SELECT id, field1, field2, field3
FROM source_table t1
WHERE
EXISTS (SELECT 1 FROM some_table s1 WHERE s1.id = t1.id) OR
EXISTS (SELECT 1 FROM some_other_table s2 WHERE s2.id = t1.id);
The possible advantage of using exists in this way is that MySQL can stop searching as soon as it finds the first matching id in either of the subqueries on the two tables. You may find that adding an index on the id columns in the two other would help (assuming that id be not already indexed):
CREATE INDEX some_idx_1 ON some_table (id);
CREATE INDEX some_idx_2 ON some_other_table (id);
This should speed up the lookup of the id in the two dependent tables.
You could work around the problem by rephrasing the query:
INSERT IGNORE INTO `destination_table` (`id`, `field1`, `field2`, `field3`)
SELECT `id`, `field1`, `field2`, `field3`
FROM `source_table`
WHERE `source_table`.`id` IN (
SELECT DISTINCT `id` FROM `some_table`
)
OR `source_table`.`id` IN (
SELECT DISTINCT `id` FROM `some_other_table`
);

MySQL select and then insert or update if exists

I need to find multiple rows related to users and then insert into another table or update if record exists for current day.
I am doing this way
SELECT CASE WHEN
(
SELECT
DISTINCT `userid`,
COUNT(DISTINCT `userip`,`userid`) AS `count`,
#date:=UNIX_TIMESTAMP(CURDATE())
FROM `tablename`
WHERE (`date` >= UNIX_TIMESTAMP(CURDATE())) GROUP BY `userid`
)
THEN
(
UPDATE `tablename2` SET `count`=`count`,`userid`=`userid`,`date`=`date` WHERE `date` >= UNIX_TIMESTAMP(CURDATE()))
)
ELSE
(
INSERT INTO `tablename2` (`count`,`userid`,`date`) VALUES(`count`,`userid`,`date`);
)
END
But this is giving me syntax error near UPDATE..
How can I fix this?
I am guessing that you want one row per user and date in tablename2. If so, enforce this rule with a unique index:
CREATE UNIQUE INDEX idx_tablename2(userid, date)
Then the database enforces it.
Your SQL is a mess, but I think I can see what you are trying to do. The basic idea is INSERT . . . ON DUPLICATE KEY UPDATE. I think the following does what you want:
INSERT INTO `tablename2` (`count`, `userid`, `date`)
SELECT `userid`, COUNT(DISTINCT `userip`, `userid`) AS `count`,
UNIX_TIMESTAMP(CURDATE())
FROM `tablename`
WHERE `date` >= UNIX_TIMESTAMP(CURDATE())
GROUP BY `userid`
ON DUPLICATE KEY UPDATE `count` = VALUES(`count`);

Select from an explicit table in mysql

I am trying to do a join on data that does not exist in my database, and never changes.
I want to do:
SELECT val, campaign FROM values
LEFT JOIN (SELECT campaign, start, end FROM (
('Spring 2104', '2014-05-01', '2014-08-01'),
('Winter 2014', '2014-08-01', '2014-12-31')
) as campaign_table ON (
values.date > campaign_table.start AND
values.date < campaign_table.end
)
Is that possible? I could create a temporary table, but for what I am trying to do that does not actually work.
You could use union all to create the dummy set. This is a viable solution considering there are only a handful of rows in your dummy dataset.
SELECT val
,campaign
FROM
VALUES
LEFT JOIN (
SELECT 'Spring 2104' campaign
,'2014-05-01' start
,'2014-08-01' [end]
UNION ALL
SELECT 'Winter 2014'
,'2014-08-01'
,'2014-12-31'
) AS campaign_table ON
VALUES.DATE > campaign_table.start
AND
VALUES.DATE < campaign_table.[end]
Maybe you need this executing all queries at once:
CREATE TABLE IF NOT EXISTS `tempo`( `campaign_name` VARCHAR(100), `from` DATE, `to` DATE );
INSERT INTO tempo(campaign_name, `start`, `end`) VALUES ('Spring 2104', '2014-05-01', '2014-08-01'),('Winter 2014', '2014-08-01', '2014-12-31');
SELECT t1.val, t1.campaign, t2.campaign_name FROM `values` t1, `tempo` t2 WHERE t1.date BETWEEN t2.start AND t2.end;
DROP TABLE `tempo`;
Also you can make: CREATE TEMPORARY TABLE
Try!

Don't insert any combination of duplicates in SQL

Right now I just have
INSERT INTO MY_TABLE (VAL1, VAL2)
SELECT VAL1, VAL2 FROM OTHER_TABLE;
However, if MY_TABLE already has the values (1, 2), I don't want to let it insert (2,1) if (2,1) is in OTHER_TABLE;
Is there a way to do this here, or even while creating the tables?
I have tried to ALTER the table and create a UNIQUE constraint but it doesn't account for duplicates
Try this.
SELECT VAL1,
VAL2
FROM OTHER_TABLE a
WHERE NOT EXISTS (SELECT 1
FROM my_table b
WHERE ( a.val1 = b.val2
AND a.val2 = b.val1 )
OR ( a.val1 = b.val1
AND a.val2 = b.val2 ))
If there is already a UNIQUE constraint on the target table, you should be able to use the IGNORE command to prevent duplicate records.
http://dev.mysql.com/doc/refman/5.5/en/insert.html
INSERT IGNORE INTO MY_TABLE (VAL1, VAL2)
SELECT VAL1, VAL2 FROM OTHER_TABLE
We can place a condition while creating the table itself:
create table my_table
(
val1 int,
val2 int,
check( val,val2 not in (select val1,val2 from other_table,my_table where my_table.val1=other_table.val2 and my_table.val2=other_table.val1)
union
select val1,val2 from my_table mt1,mt2 where mt1.val1=mt2.val2 and mt1.val2=mt2.val1))
);

insert data from one table to another in mysql

i want to read all data from one table and insert some data in to another table. my query is
INSERT INTO mt_magazine_subscription (
magazine_subscription_id,
subscription_name,
magazine_id,
status )
VALUES (
(SELECT magazine_subscription_id,
subscription_name,
magazine_id
FROM tbl_magazine_subscription
ORDER BY magazine_subscription_id ASC), '1')
but i got an error that
#1136 - Column count doesn't match value count at row 1
please help me.
You can use INSERT...SELECT syntax. Note that you can quote '1' directly in the SELECT part.
INSERT INTO mt_magazine_subscription (
magazine_subscription_id,
subscription_name,
magazine_id,
status )
SELECT magazine_subscription_id,
subscription_name,
magazine_id,
'1'
FROM tbl_magazine_subscription
ORDER BY magazine_subscription_id ASC
If you want insert all data from one table to another table there is a very simply sql
INSERT INTO destinationTable (SELECT * FROM sourceDbName.SourceTableName);
It wont work like this.
When you try to insert the row using a query all values should be there in query.
With the above problem you want to insert
magazine_subscription_id, subscription_name, magazine_id, status
in select query you have
magazine_subscription_id, subscription_name, magazine_id, status 1 it is not possible.
If you want to insert either you need to insert using query of direct values
Actually the mysql query for copy data from one table to another is
Insert into table2_name (column_names) select column_name from table1
where, the values copied from table1 to table2
If there is a primary key like "id" you have to exclude it for example my php table has: id, col2,col3,col4 columns. id is primary key so if I run this code:
INSERT INTO php (SELECT * FROM php2);
I probably get this error:
#1062 - Duplicate entry '1' for key 'PRIMARY'
So here is the solution, I excluded "id" key:
INSERT INTO php ( col2,col3,col4) (SELECT col2,col3,col4 FROM php2);
So my new php table has all php2 table rows anymore.
INSERT INTO mt_magazine_subscription (
magazine_subscription_id,
subscription_name,
magazine_id,
status )
VALUES (
(SELECT magazine_subscription_id,
subscription_name,
magazine_id,'1' as status
FROM tbl_magazine_subscription
ORDER BY magazine_subscription_id ASC));
Insert data from one table to other with condition in MySQL and same will work in SQL Server as well. Only non existing data will get updated. Both table have same structure so column need not to pass.
insert into table_A
select * from table_A_copy
where not exists
(
select * from table_A where table_A_copy.clm_a=table_A.clm_a and table_A_copy.clm_b=table_A.clm_b and table_A_copy.clm_c=table_A.clm_c
);
Try this. Your doing in wrong way.
INSERT INTO mt_magazine_subscription(
magazine_subscription_id,
subscription_name,
magazine_id, status) VALUES (
(SELECT magazine_subscription_id, subscription_name,
magazine_id,1 as status FROM tbl_magazine_subscription
ORDER BY magazine_subscription_id ASC)
)
INSERT INTO mt_magazine_subscription (
magazine_subscription_id,
subscription_name,
magazine_id,
status )
VALUES (
(SELECT magazine_subscription_id,
subscription_name,
magazine_id,'1' as status
FROM tbl_magazine_subscription
ORDER BY magazine_subscription_id ASC))
Try to use this
INSERT INTO mt_magazine_subscription (
magazine_subscription_id,
subscription_name,
magazine_id,
status )
SELECT magazine_subscription_id,
subscription_name,
magazine_id,
'1'
FROM tbl_magazine_subscription
ORDER BY magazine_subscription_id ;
Use the hard coded value in select clause
INSERT INTO destination_table (
Field_1,
Field_2,
Field_3)
SELECT Field_1,
Field_2,
Field_3
FROM source_table;
BUT this is a BAD MYSQL
Do this instead:
drop the destination table: DROP DESTINATION_TABLE;
CREATE TABLE DESTINATION_TABLE AS (SELECT * FROM SOURCE_TABLE);
INSERT INTO mt_magazine_subscription SELECT *
FROM tbl_magazine_subscription
ORDER BY magazine_subscription_id ASC