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
Related
I have a mysql table with only 3 columns (id - primary key / status / timestamp). Periodically I receive a status message which can be 0 or 1 and I need to insert it in that table but only if the last status inserted is different.
Is there any way to do this is only one mysql query ?
Basically I need to do this :
SELECT status FROM `status_e_distr_c01` order by id DESC LIMIT 1
Then compare my status message with select result and if is different then do insert, if not...do nothing...
So how can I do this in one mysql query ?
Thank you very much
Assuming that the values of the columns that you want to insert are :status, :timestamp you can do it like this:
INSERT INTO status_e_distr_c01 (status, timestamp)
SELECT :status, :timestamp
FROM dual
WHERE :status <>
COALESCE((SELECT status FROM status_e_distr_c01 ORDER BY id DESC LIMIT 1), NOT :status)
The code will work even if the table is empty.
You may omit FROM dual if your version of MySql is 5.7+.
See a simplified demo.
INSERT INTO status_e_distr_c01 (status)
SELECT #new_status
FROM ( SELECT status
FROM status_e_distr_c01
ORDER BY ts DESC LIMIT 1 ) subquery
WHERE subquery.status != #new_status;
PS. Will fail if destination table is empty. The most first row must be inserted without thes checking.
UPDATE
INSERT INTO status_e_distr_c01 (status)
SELECT #new_status
WHERE #new_status != COALESCE(( SELECT status
FROM status_e_distr_c01
ORDER BY ts DESC LIMIT 1 ), 2);
Works on empty table too.
fiddle
The same as stored procedure:
CREATE PROCEDURE insert_if_changed (IN new_status INT)
INSERT INTO status_e_distr_c01 (status)
SELECT new_status
WHERE new_status != COALESCE(( SELECT status
FROM status_e_distr_c01
ORDER BY ts DESC LIMIT 1 ), 2);
fiddle
You can use an INSERT ... SELECT ... FROM the dual pseudo table and check if the target table is empty or the new status differs from the last one selected in a subquery.
INSERT INTO status_e_distr_c01
(status)
SELECT ?
FROM dual
WHERE NOT EXISTS (SELECT *
FROM status_e_distr_c01)
OR ? <> (SELECT status
FROM status_e_distr_c01
ORDER BY id DESC
LIMIT 1);
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`
);
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`);
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!
I create a temporary table #tbl(account, last_update). I have following two inserts from different source (could be tables from different databases) to insert account with last update date. For example
create table #tbl ([account] numeric(18, 0), [last_update] datetime)
insert into #tbl(account , last_update)
select table1.account, max(table1.last_update)
from table1 join…
group by table1.account
insert into #tbl(account , last_update)
select table2.account, max(table2.last_update)
from table2 join…
group by table2.account
The problem is this could cause duplicate account in the table #tbl. I either have to avoid it during each insert or remove the duplicate after both insert. Also, if there is account with two different last_update, I want the #tbl have the latest last_update. How do I achieve this conditional insert? Which one will have better performance?
Do you think you could rewrite your query to something like:
create table #tbl ([account] numeric(18, 0), [last_update] datetime)
insert into #tbl(account , last_update)
select theaccount, MAX(theupdate) from
(
select table1.account AS theaccount, table1.last_update AS theupdate
from table1 join…
UNION ALL
select table2.account AS theaccount, table2.last_update AS theupdate
from table2 join…
) AS tmp GROUP BY theaccount
The UNION ALL will build you 1 unique table combining table1 + table2 records. From there, you can act as if was a regular table, which means that you are able to find the max last_update for each record using a "group by"
insert into #tbl(account , last_update)
select account, last_update
from
(
select a.* from #table1 a where
last_update in( select top 1 last_update from #table1 b
where
a.account = b.account
order by last_update desc)
UNION
select a.* from #table2 a where
last_update in( select top 1 last_update from #table2 b
where
a.account = b.account
order by last_update desc)
) AS tmp