I have two tables with the following layout ...
------------- -------------------------
| Master | | History |
------------- -------------------------
| id | name | | id | name | master_id |
------------- -------------------------
The history table contains rows where the master_id is NULL. Those I copy into the master table.
INSERT master (name)
SELECT name
FROM histories h
WHERE h.master_id = NULL
How can I update the master_id in the history table with the id of the associated object in the master table? This update should happen in the same step as the insertion is made. I use MySQL if this is of interest.
It is possible to insert into master table records with IDs based on some information from the other table.
For example, you can use the histories.id + last master.id:
LOCK TABLES master WRITE, histories AS h WRITE;
SELECT id FROM master ORDER BY id DESC LIMIT 1 INTO #last_master_id;
INSERT INTO master (id, name)
SELECT h.id + #last_master_id, h.name FROM histories h;
UPDATE histories h SET h.master_id = h.id + #last_master_id;
UNLOCK TABLES;
This works as long as you use integer IDs and if you don't mind that the new ID is based on the other one.
If you wanted to use some non-deterministic IDs, such as UUIDs, the solution would require a few more steps:
Add a temporary column to the histories table.
Fill with the new IDs (update histories set tmp_uuid = UUID(), something like that).
Insert into master select tmp_uuid from histories...
Update histories
Drop the temporary column.
One advantage of using UUIDs is that you don't need to lock the tables. You don't need to worry about other session inserting a record and taking your ID, because the other session generates a different ID.
The SQL documentation here: http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
suggests that you should be able to do something like the following:
INSERT master (name)
SELECT name, id
FROM history h
WHERE h.master_id = NULL
UPDATE History SET master_id = LAST_INSERT_ID()
WHERE History.id = h.id;
Though I'm not 100% on the syntax as I don't have a SQL instance I can run this against.
Related
I have two tables in MySQL and I would like to update a column in one of them to match values from another.
The tables each have a customer and part number column.
Table 1:
Customer_Name | Part_Number | Demand | Allocation
Table 2:
Customer_Name | Part_Number | Demand
I want to update table 1 to add table 2 demand to the allocation figure in table 1, if the part number and customer both exist in table 2.
A query I have attempted so far:
UPDATE `Packing_Dispatch` SET Allocation = `Packing_Allocation`.Demand WHERE
Customer_Name = `Packing_Allocation`.Customer_Name AND Part_Number = `Packing_Allocation`.Part_Number
How can I do this?
You can try below
UPDATE `Packing_Dispatch`
Join `Packing_Allocation`
SET Allocation = `Packing_Allocation`.Demand
WHERE Customer_Name = `Packing_Allocation`.Customer_Name AND Part_Number = `Packing_Allocation`.Part_Number
Let's suppose I have the following table in a MySQL DB
Table: Debt
ID | Customer | Amount
---------------------
1 | Peter | $ 80
2 | John | $120
What I want to do is sum a new amount of money to the already pending one for a given customer. What I've been doing so far is a SELECT to check if the customer exist in the table. If it does then I UPDATE the register with the sum of the previous value plus the new one. If the register doesn't exist the I proceed to INSERT.
As you can see I'm using two operations, a SELECT and an UPDATE, or a SELECT and and INSERT.
My question is if there is a way to do this with only one single operation
https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
Set amount = amount + ?? in the on duplicate update clause.
MySql does allow to update an existing record or insert one, use INSERT INTO table (id, name, amount) VALUES (1, 'Peter', 80) ON DUPLICATE KEY UPDATE;
I don't know though if you could use the existing value to do a sum with the new and insert the result.
Probably you'd need triggers for that...
I am merging two tables that have the potential to have the same primary key (id) which will produce a Duplicate entry error.
I am OK with having new primary keys generated for the inserted data or even the existing data, so if the example databases are:
table_a
Id | Name
----------
1 | Jack
----------
2 | Jill
----------
3 | John
----------
table_b
Id | Name
----------
1 | Jim
----------
2 | Jenny
----------
3 | Joy
----------
And the Import script is INSERT INTO table_a SELECT * FROM table_b;
How do I get the script to assign new ids when they are detected as duplicate?
I realise I could do INSERT INTO table_a (name) SELECT name FROM table_b, in a similar way to that described on Merge and update primary key, but I have nearly 100 tables of different structures that I need to merge and would prefer to be able to use SELECT * and assign new ids.
You need to add another column which specifies the type of the result table.
For example in the table_a (Result table) you should add a column named type of INT type (Or of BIT type here), then you need to specify for example 0 means the data for table_a and 1 means the data for table_b.
So in the result table (table_a) you have following fields:
Id (INT - P.K. AutoIncrement)
Type (INT)
TableRelatedId (INT as you already defined)
Name (VARCHAR as you already defined)
Before inserting record you first update the table 'table_a' by type 0
UPDATE table_b SET type = 0
and then merge table_b with table_a by following INSERT:
INSERT table_a([Type], TableRelatedId, Name) SELECT 1, Id, Name FROM table_b
I need to insert some data in a table named ‘queue’ which is a patient queue in a particular date . Two fields data will be inserted .Two fields name are ‘PatientID’ and ‘Visiting Date’. Table ‘queue' like
QueueID | PatientID | Visiting_date |
-------------|-------------------|-------------------------|
1 | 4 | Current date |
table:queue
But while inserting the record there are two conditions :
Condition 1 : patitentID comes from patient table (given below)
Condition 2 : one record will be inserted to ‘queue’ table if it does not exist to prevent repeatation.ie PatientID=4 will not be inserted if already inserted.
-------------|-----------------|------------------|
patitentID | Patient Name | Contact no |
-------------|-----------------|------------------|
4 | David | 01245785874 |
table:patient
My SQL is: (it does not work)
INSERT INTO `queue`(`patientID`, `Visiting_date`)
SELECT patient.`patientID`,’CURDATE()’ FROM `patient`
WHERE NOT EXISTS (
SELECT `patientID`, `visiting_date`FROM `queue`
WHERE `patientID` = '4' AND `visting_date`=CURDATE()
) LIMIT 1;
You could set a foreign key to make sure the patients id exists.
In the Queue table you can set patientID as unique, this makes sure you can insert only unique id's in the queue table.
Also if you would like to be able to insert the same userID but with different dates you could specify unique constraint for multiple columns in MySQL.
If you want to solve it with a mysql query only you can use this question.
I would use a separate query to check if there is a user with that ID in that table.
SELECT * FROM queue WHERE PatientID = 4;
and then check the result of that query, if it returns a row, that means that there is a user in there and you don't do anything.
If the query doesn't return a row, that means you can now use a query to inert a user. Like this
INSERT INTO queue (PatientID, VisitingDate);
I have a table contains columns like:
time tv_program user_name
xxx friends John
xxx Game of Thrones Kate
...
...
Now I want to create separate index table for tv_program and user_name like:
id tv_program
1 friends
2 Game of Thrones
3 ...
4 ...
id user_name
1 John
2 Kate
3 ...
4 ...
and update the original table, replace the tv_program and user_name with the index number instead like
time tv_program user_name
xxx 1 1
xxx 2 2
... ... ...
Is there any simple way to do this? many thanks!!
You basically want to normalise your data, and you can do it with MySQL queries:
Create a table tv_programs table with id autoincrement, name index unique
INSERT INTO tv_programs (name) SELECT DISTINCT tv_program
FROM original_table
Now you have a table containing the programs, with their id automatically created by MySQL, so you now have to run an UPDATE with join (using string names, could be slow if you have lots of data and no index, but you just run it once) and update the original table with the id of the joined table (tv_programs)
UPDATE original_table ot LEFT JOIN tv_programs tp ON ot.tv_program = tp.name SET ot.tv_program = tp.id
And now you can change the type of tv_program column to INT
Repeat with the other table. Do backups before, or add a column to the original table (e.g. tv_program_id) and update that one with IDs, so that you can run other queries to check the results before dropping the old column and continue
Hope that's clear.