I have two databases, one which is old and one which is new. I need to copy one particular column from the old to the new. Structure-wise they are both totally identical, although the new table is significantly larger than the old, and the only way i can connect these two tables together by a foreignkey is the uni_id, which is just a normal integerfield, but its unique.
So this is basically the structure of the table:
| id | name | name_pseudo | uni_id |
------------------------------------------------------------
I want to compare each row of new_db.mytable with old_db.mytable by uni_id and insert old_db.mytable.name_pseudo into new_db.mytable.name_pseudo.
Can such expression in pure MySQL be constructed?
From the MySQL manual on UPDATE
You can also perform UPDATE operations covering multiple tables. However, you cannot use ORDER BY or LIMIT with a multiple-table UPDATE. The table_references clause lists the tables involved in the join. Its syntax is described in Section 13.2.9.2, “JOIN Syntax”. Here is an example:
UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;
Which in your case should read like:
UPDATE newdb.mytable AS new, old_db.mytable AS old
SET new.name_pseudo=old.name_pseudo
WHERE old.uni_id=new.uni_id;
I had a table name called emp-reg in mysql.When I gave desc emp-reg it showed me an error.
Where as when I changed the table name RENAME TABLE emp-reg TO emp and then gave desc emp it worked perfectly.Why is desc not working for-
what will happen if we perform insert operation in table such asemp-reg?
Instead, you can use _ under score.
- is treated as minus sign and hence is rejected.
Or you can use back ticks around the name with - in it. Say
`emp-reg`.
If you want to rename any of such columns in your table, use alter table command with change option.
ALTER TABLE table_name CHANGE COLUMN `old-col-name` `new_col_name` int
You can use any desired or matching data type for the column with the earlier definition.
Does MySQL have an UPDATE syntax that would allow me to update a whole row (not individual columns)?, something like this:
UPDATE `table1`
LEFT JOIN `table2` USING (`myColumn`)
SET `table1`.* = `table2`.*
Both table1 and table2 have the exact same structure.
The column names are variable, and subject to change.
Unfortunately I can't use a REPLACE query because the tables were badly designed and I'm not at liberty to modify them. The joining column doesn't have a unique index assigned to it, it only has a normal index.
"The column names are variable, and subject to change" - This is so wrong, if you rely on column order not col names, one day it will hit you in the head. Update will work with explicit col names: sqlfiddle.
When I imported a table with 30 million rows from a text file to a MYSQL table it only took 1 minute. However, I realized that I missed a column and that I needed to add it to the table. From the MYSQL command line, I wrote the following command:
create tableC as(tableA.T1, tableB.ZID from tableA, table B where A.ZID = B.ZID)
It's been over one hour and the command has not terminated. Does anyone know the reason why? TableB was already in the MYSQL server.
Not 100% sure but you might be better off altering the table first and adding the column, then doing an update to populate that column
ALTER TABLE tableB ADD COLUMN colA yourColumnDefinition;
UPDATE tableB SET colA = <however you do it>;
I'm not totally sure which table you are adding the column to or how you are computing it. Based on the query you posted it looks like you are creating a mapping table to map two table's IDs to each other. If that is the case you would probably be better off putting a foreign key in one of the tables.
Again, this might not be exactly what you are looking for but if you just want to add a column to a table you already created this might be a better approach.
I got a table with a normal setup of auto inc. ids. Some of the rows have been deleted so the ID list could look something like this:
(1, 2, 3, 5, 8, ...)
Then, from another source (Edit: Another source = NOT in a database) I have this array:
(1, 3, 4, 5, 7, 8)
I'm looking for a query I can use on the database to get the list of ID:s NOT in the table from the array I have. Which would be:
(4, 7)
Does such exist? My solution right now is either creating a temporary table so the command "WHERE table.id IS NULL" works, or probably worse, using the PHP function array_diff to see what's missing after having retrieved all the ids from table.
Since the list of ids are closing in on millions or rows I'm eager to find the best solution.
Thank you!
/Thomas
Edit 2:
My main application is a rather easy table which is populated by a lot of rows. This application is administrated using a browser and I'm using PHP as the intepreter for the code.
Everything in this table is to be exported to another system (which is 3rd party product) and there's yet no way of doing this besides manually using the import function in that program. There's also possible to insert new rows in the other system, although the agreed routing is to never ever do this.
The problem is then that my system cannot be 100 % sure that the user did everything correct from when he/she pressed the "export" key. Or, that no rows has ever been created in the other system.
From the other system I can get a CSV-file out where all the rows that system has. So, by comparing the CSV file and my table I can see if:
* There are any rows missing in the other system that should have been imported
* If someone has created rows in the other system
The problem isn't "solving it". It's making the best solution to is since there are so much data in the rows.
Thanks again!
/Thomas
We can use MYSQL not in option.
SELECT id
FROM table_one
WHERE id NOT IN ( SELECT id FROM table_two )
Edited
If you are getting the source from a csv file then you can simply have to put these values directly like:
I am assuming that the CSV are like 1,2,3,...,n
SELECT id
FROM table_one
WHERE id NOT IN ( 1,2,3,...,n );
EDIT 2
Or If you want to select the other way around then you can use mysqlimport to import data in temporary table in MySQL Database and retrieve the result and delete the table.
Like:
Create table
CREATE TABLE my_temp_table(
ids INT,
);
load .csv file
LOAD DATA LOCAL INFILE 'yourIDs.csv' INTO TABLE my_temp_table
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
(ids);
Selecting records
SELECT ids FROM my_temp_table
WHERE ids NOT IN ( SELECT id FROM table_one )
dropping table
DROP TABLE IF EXISTS my_temp_table
What about using a left join ; something like this :
select second_table.id
from second_table
left join first_table on first_table.id = second_table.id
where first_table.is is null
You could also go with a sub-query ; depending on the situation, it might, or might not, be faster, though :
select second_table.id
from second_table
where second_table.id not in (
select first_table.id
from first_table
)
Or with a not exists :
select second_table.id
from second_table
where not exists (
select 1
from first_table
where first_table.id = second_table.id
)
The function you are looking for is NOT IN (an alias for <> ALL)
The MYSQL documentation:
http://dev.mysql.com/doc/refman/5.0/en/all-subqueries.html
An Example of its use:
http://www.roseindia.net/sql/mysql-example/not-in.shtml
Enjoy!
The problem is that T1 could have a million rows or ten million rows, and that number could change, so you don't know how many rows your comparison table, T2, the one that has no gaps, should have, for doing a WHERE NOT EXISTS or a LEFT JOIN testing for NULL.
But the question is, why do you care if there are missing values? I submit that, when an application is properly architected, it should not matter if there are gaps in an autoincrementing key sequence. Even an application where gaps do matter, such as a check-register, should not be using an autoincrenting primary key as a synonym for the check number.
Care to elaborate on your application requirement?
OK, I've read your edits/elaboration. Syncrhonizing two databases where the second is not supposed to insert any new rows, but might do so, sounds like a problem waiting to happen.
Neither approach suggested above (WHERE NOT EXISTS or LEFT JOIN) is air-tight and neither is a way to guarantee logical integrity between the two systems. They will not let you know which system created a row in situations where both tables contain a row with the same id. You're focusing on gaps now, but another problem is duplicate ids.
For example, if both tables have a row with id 13887, you cannot assume that database1 created the row. It could have been inserted into database2, and then database1 could insert a new row using that same id. You would have to compare all column values to ascertain that the rows are the same or not.
I'd suggest therefore that you also explore GUID as a replacement for autoincrementing integers. You cannot prevent database2 from inserting rows, but at least with GUIDs you won't run into a problem where the second database has inserted a row and assigned it a primary key value that your first database might also use, resulting in two different rows with the same id. CreationDateTime and LastUpdateDateTime columns would also be useful.
However, a proper solution, if it is available to you, is to maintain just one database and give users remote access to it, for example, via a web interface. That would eliminate the mess and complication of replication/synchronization issues.
If a remote-access web-interface is not feasible, perhaps you could make one of the databases read-only? Or does database2 have to make updates to the rows? Perhaps you could deny insert privilege? What database engine are you using?
I have the same problem: I have a list of values from the user, and I want to find the subset that does not exist in anther table. I did it in oracle by building a pseudo-table in the select statement Here's a way to do it in Oracle. Try it in MySQL without the "from dual":
-- find ids from user (1,2,3) that *don't* exist in my person table
-- build a pseudo table and join it with my person table
select pseudo.id from (
select '1' as id from dual
union select '2' as id from dual
union select '3' as id from dual
) pseudo
left join person
on person.person_id = pseudo.id
where person.person_id is null