I have a dynamic amount of tables with the same column structure. I wish to update certain rows in all of them with a single query. Any multi-table UPDATE examples I've found have to do with doing different columns in different tables, and updating one table based on the value in another table. My issue is that I have the same column in all tables, and it is a dynamic number of tables.
As an example of this, I would have table_a, table_b, and table_c. All three tables would share the same structure: id and status.
I want to update the status column in all three at once to a known value.
This is the queries that I would like to essentially combine in this example.
UPDATE table_a SET status = 'closed' WHERE id = 5
UPDATE table_b SET status = 'closed' WHERE id = 5
UPDATE table_c SET status = 'closed' WHERE id = 5
Since the amount of tables is dynamic, I feel this would be cleanest with a single query. I have an array of the table names in PHP (loaded dynamically for this system) and can iterate them to form joins or concatenate a string if needed.
Here is an example of what I thought would work.
UPDATE table_a, table_b, table_c
SET status = 'closed'
WHERE id = 5
The problem with this query is that I get an error about ambiguity for the column names.
Do I need to make it like something this?
UPDATE table_a, table_b, table_c
SET table_a.status = 'closed', table_b.status = 'closed', table_c.status = 'closed
WHERE table_a.id = 5 OR table_b.id = 5 OR table_c.id = 5
I'm assuming this would work and might not be too bad, as the expected amount of tables really ranges from 1-10 maybe. However, I was really hoping for a more efficient way. Firing off individual queries might not be so bad with that few of queries, but in a big system every bit of optimization counts!
Thank you for any help.
Please note that the structure of having multiple tables with the same scheme is by design, as it is a tracker system that separates multiple locations. The example only reflects the basic structure of the idea I need to implement; the real thing is much more complicated. Also, stored procedures will not be an option in this project.
Yes, you'll need to qualify each table / column that you want to update if they use the same logical names.
The query sees you're looking for a logical name of 'status', but you've defined 'status' to be the logical name for 3 different physical locations in the database. Which one did you mean? There are many things that can be done when multiple tables are involved. So for a database to assume you want to update all of them would be very bad.
Related
I'm trying to get the content of 3 different tables.
table A = Is containing our users list, table B = Is returning contracts related to users,table C = Is returning formula details related to the contracts.
In order to make it the right way, I'm using the following multi table request:
SELECT * FROM rscm_students A, rscm_files B, rscm_formulas C
WHERE B.dossier_status = 0
AND A.student_agency = :agency
AND B.file_student_id = A.id
AND B.file_formula_id = C.id
AND C.formula_place = 0
GROUP BY A.student_uniqid
ORDER BY B.file_date_create";
This is where the whole damn thing become a little complicated. It is returning the correct datas, but as the primary key of every table here is called "id". I can't do some foreach in php. If I got 3 contracts on 1 user, it impossible for me to regroup every contract in the same user array.
I'm still not an expert in SQL, that's why I'm using Phinx to control my database. This is also why my primary keys are named "id".
If you have a good idea, please let me know!
Alright, I will make an answer out of it.
First off, don't use
select *
The above select is fine for quick and dirty development prior to production. But it makes a mess out of things such as your joins with common column names coming out of multiple tables (like id and others).
Use modern explicit join syntax. Don't use the older join style. So use join and on.
Lastly with table aliases, create unique output column names for the id columns or other clashes such as
A.id as aid, B.id as bid
There are many varied posts about this matter, but I am unable to find the answer I need. I am hoping this question is unique.
I am trying to append all the data from one table to another, without creating new records. The data in the second table is really a subset of data for a portion of the existing records in the first table.
For example:
I have the table "SPK". And I want to write all of the data from SPK into the table "RCT". The common field between each record I want to match is the RegID, which is unique in both tables (i.e. there is only one SPK record per RCT record).
If I understand correctly, you mean append the columns in one table (call it SECOND) to the other (call it FIRST).
In that case, does this work ?
UPDATE
regcontactsTest
JOIN
speakersTest
ON speakersTest.RegistrationID = regcontactsTest.RegistrationID
SET regcontactsTest.presentationtitle = speakersTest.presentationtitle
EDIT: Updated the query based on Mariadb syntax
You need to use JOIN. For general Update join :
update tab1 a
join tab2 b ON a.join_colA = b.join_colB
SET a.columnToUpdate = [something]
Or in other words:
update
tab1 a
join tab2 b on ..
set a.field=...;
I had an issue joining multiple tables to retrieve the data I needed. In order to accomplish the proper results I had to first create a view (shown below) called: vwinvgrossrev :
SELECT dbo.inv_item.inv_num, dbo.inv_item.co_line,
dbo.inv_hdr.co_num, dbo.inv_hdr.inv_date, dbo.inv_item.qty_invoiced,
dbo.inv_item.price
FROM dbo.inv_item INNER JOIN
dbo.inv_hdr ON dbo.inv_item.inv_num = dbo.inv_hdr.inv_num
and then I had to join the view on my final table in order to create a proper summation of the values that I wanted
select sum(vwinvgrossrev.qty_invoiced*vwinvgrossrev.price)
from vwinvgrossrev,coitem
WHERE vwinvgrossrev.co_num=coitem.co_num
AND coitem.Uf_Erne='Y'
AND vwinvgrossrev.co_line=coitem.co_line
AND DATEPART(mm,vwinvgrossrev.inv_date) = DATEPART(mm,Getdate())
AND YEAR(vwinvgrossrev.inv_date) = YEAR(Getdate())
My question is this. Is there anyway to do this in a single query. The problem is all 3 tables have a many to many relationship with one another and always returns the wrong value when joining all 3 tables.
If your current query (using the view) gives you what you are looking for then I believe that this query will give you the same thing in a single query:
SELECT sum(inv_item.qty_invoiced*inv_item.price)
FROM inv_item
JOIN inv_hdr ON dbo.inv_item.inv_num = dbo.inv_hdr.inv_num
JOIN coitem ON (inv_hdr.co_num=coitem.co_num
AND inv_item.co_line=coitem.co_line)
WHERE coitem.Uf_Erne='Y'
AND vwinvgrossrev.co_line=coitem.co_line
AND DATEPART(mm,inv_hdr.inv_date) = DATEPART(mm,Getdate())
AND YEAR(inv_hdr.inv_date) = YEAR(Getdate())
However, I'll be surprised if that is what you are looking for.
I am assuming that you don't actually have a many-to-many between all 3. I am assuming that inv_hdr has a unique inv_num and inv_item has many of those. Similarly I am assuming that co_num is unique within inv_hdr but has multiple occurrences within coitem. These are not many-to-many but rather 1-to-many relationships. Since SELECT multiplies rows I think you are going to be summing way more than you want.
Why do you want to include coitem at all if you are just interested in inv_item.qty_invoiced and inv_item.price? Is it just to limit on the Uf_Erne column? Is coitem always going to have either 1 or 0 records for that co_num and co_line with Uf_Erne='Y'?
In sum, I've reproduced your query in a single query without a view, but I think you may need to think through whether this is really what you want.
You need to refine your database schema to normalise out the many-to-many relationships. That is a given and is standard practice regardless of your current problem. The fact that it will simplify your current problem is the reason why. There are many tutorials/blog/etc out there to show you how to do this with join tables so I am not going into it here.
I have three tables. One is a table of deletion candidates. This table was created with certain criteria, but did not include a couple of factors for consideration (limitations of the system). The other two tables were created considering those "left out" factors. So, I need to run a SELECT query on these three tables to come up with a deletion list.
What I started with is:
SELECT inactive.id
FROM inactive, renamed, returned
WHERE NOT EXISTS (inactive.id = remamed.id and inactive.id = returned.id)
But this is giving me an error. Can someone point out my error here?
Thank you
It's not entirely clear what you are trying to do here.
I assume you want a list of all rows from the inactive table that do not exist in either the renamed table or the inactive table. Is that right?
If so you can use a query like this:
SELECT inactive.id
FROM inactive
WHERE NOT EXISTS (select null from renamed where renamed.id = inactive.id)
AND NOT EXISTS (select null from returned where returned.id = inactive.id)
I have a database with two separate tables. One table (T1) has 400+ values in its only column, while the other (T2) has 14,000+ rows and multiple columns.
What I need to do is to compare the column in T1 to one column in T2. For every matching value, I need to update a different value in the same row in T2.
I know this is pretty easy and straight-forward, but I'm new to MySQL and trying to get this down before I go back to other things. Thanks a ton in advance!
EDIT: Here's what I've been trying to no avail..
UPDATE `apollo`.`Source`, `apollo`.`Bottom`
SET `Source`.`CaptureInterval` = '12'
WHERE `Bottom`.`URL` LIKE `Source`.`SourceID`
EDIT 2:
A little clarification:
apollo.Bottom and apollo.Source are the two tables.
apollo.Bottom is the table with one column and 400 records in that column.
I want to compare Bottom.URL to Source.SourceID. If they match, I want to update Source.CaptureInterval to 12.
You can use the following query to update. But the performance will be much better if you index URL and SourceID columns in both tables as they are being used in the WHERE clause.
UPDATE `apollo`.`Source`, `apollo`.`Bottom`
SET `Source`.`CaptureInterval` = '12'
WHERE `Bottom`.`URL` = `Source`.`SourceID`
You can join the two tables together and do a multiple table update.
Start with something like this:
UPDATE `apollo`.`Source`
INNER JOIN `apollo`.`Bottom` ON `apollo`.`Bottom`.`URL` = `apollo`.`Source`.`SourceID`
SET `apollo`.`Source`.`CaptureInterval` = '12';