Running an UPDATE query within MySQL (with relationships) - mysql

Some of you will have seen me trying to learn how to run UPDATE queries on MySQL (for those of you who helped out - THANK YOU). However, whilst progress has certainly been made, I am still struggling to simply update one column with data from another - and can't get it to work.
If I run the following SELECT query, I see several thousand records that match
SELECT
`agr_addressbook`.`gtxr2_product_family` AS `gtxr2_product_family`,
`gtxuk_r2_machine`.`product_family` AS `product_family`
FROM (((`agr_addressbook`
JOIN `agr_addressbook_extra` ON ((`agr_addressbook`.`contact_id` = `agr_addressbook_extra`.`contact_id`)))
JOIN `gtxuk_machine` ON ((`agr_addressbook_extra`.`contact_value` = `gtxuk_machine`.`machine_id`)))
JOIN `gtxuk_r2_machine` ON ((CONVERT(`gtxuk_machine`.`machine_desc` USING utf8) = `gtxuk_r2_machine`.`machine_desc`)))
WHERE (`agr_addressbook_extra`.`contact_name` = 'mac_type')
However, when I run the following update query - it doesn't update a single value - meaning that I have messed up somewhere:
UPDATE agr_addressbook ea
JOIN agr_addressbook_extra eae ON eae.contact_id = ea.contact_id
JOIN gtxuk_machine hm ON hm.machine_id = eae.contact_value
JOIN gtxuk_r2_machine hrm ON hrm.machine_desc = CONVERT(hm.machine_desc USING utf8)
SET ea.gtxr2_product_family = hrm.product_family
WHERE eae.contact_name = 'mac_type'
Can anyone see where I'm going wrong?
Thank you (yet again).

This (or something very similar) might work:
UPDATE agr_addressbook ea
SET ea.gtxr2_product_family = (
SELECT hrm.product_family FROM agr_addressbook_extra eae
JOIN gtxuk_machine hm ON hm.machine_id = eae.contact_value
JOIN gtxuk_r2_machine hrm ON hrm.machine_desc = CONVERT(hm.machine_desc USING utf8)
WHERE eae.contact_name = 'mac_type' AND eae.contact_id = ea.contact_id)
Your problem may have to do with the way that UPDATE parameters work. Think about how you are passing a JOINed table as the table to perform changes to.

Related

Mysql Can I make an update with join

I have a database with several tables and all my queries work but I would like to had a new one and can't succeed to make it working.
Two tables 'vins' and 'producteurs'with a foreign key IDproducteur in my 'vins' table.
I need to update the 'vins'table from an excel source where the data are not always written corectly and need to change the stock value for some records of the 'vins' table.The p.nomproducteur and V.annee and v.nom are parameters but for test I put hard values.
My Query is the following:
UPDATE vins AS v
JOIN producteurs p
ON ( p.IDproducteur = v.IDproducteur AND p.nomproducteur LIKE "Charles" )
SET stock = 10
WHERE v.nom LIKE "Symphonie" AND v.annee = 2013
I have two records where the producteur is "Charles" and V.nom is Symphonie one withe annee = 2010 and one with 2013. I got no error in phpMyadmin but there is no results to my Query even by changing some command order.
Is what I want impossible to do?.
Put the condition p.nomproducteur LIKE "Charles" in the WHERE clause:
UPDATE vins v
JOIN producteurs p ON p.IDproducteur = v.IDproducteur
SET stock = 10
WHERE
v.nom = "Symphonie" AND v.annee = 2013 AND p.nomproducteur = "Charles"
Also there is no need for LIKE in this case, a simple = will do.
The update based on JOIN is commonly used in mysql so be sure that your join and where condition really match the values in your tables
UPDATE vins AS v
INNER JOIN producteurs p ON p.IDproducteur = v.IDproducteur
SET v.stock = 10
WHERE v.nom = "Symphonie"
AND v.annee = 2013
AND p.nomproducteur = "Charles"
and do the fact you are not filter for partial string use = instead of like

SQL with 3 criteria using Access

Morning All
I am using Access 2010 and currently have the below SQL which works fine:
Code:
DELETE DISTINCTROW tbl_added.*
FROM tbl_added INNER JOIN tbl_removed ON (tbl_added.SPECIAL_NEED_TYPE = tbl_removed.SPECIAL_NEED_TYPE) AND (tbl_added.NUM_CUST = tbl_removed.NUM_CUST);
I am trying to add another criteria but getting an error:
Code:
DELETE DISTINCTROW tbl_added.*
FROM tbl_added INNER JOIN tbl_removed ON (tbl_added.SPECIAL_NEED_TYPE = tbl_removed.SPECIAL_NEED_TYPE) AND (tbl_added.NUM_CUST = tbl_removed.NUM_CUST) AND (tbl_added.ADDED_REMOVAL_DT < tbl_removed.ADDED_REMOVAL_DT) ;
Error Received:
Could not delete from specified tables
The last criteria I have added is a date
When joining on any operator that is not =, your recordset becomes non-updateable. That means that you can't edit or delete.
You could move all comparisons to the WHERE clause, and use a CROSS JOIN instead, like this:
DELETE DISTINCTROW tbl_added.*
FROM tbl_added, tbl_removed
WHERE (tbl_added.SPECIAL_NEED_TYPE = tbl_removed.SPECIAL_NEED_TYPE) AND (tbl_added.NUM_CUST = tbl_removed.NUM_CUST) AND (tbl_added.ADDED_REMOVAL_DT < tbl_removed.ADDED_REMOVAL_DT) ;
However, that's still not updateable, since a CROSS JOIN is not updateable.
The solution is to keep all = comparisons in the INNER JOIN, and move all other comparisons to the WHERE clause:
DELETE DISTINCTROW tbl_added.*
FROM tbl_added INNER JOIN tbl_removed ON (tbl_added.SPECIAL_NEED_TYPE = tbl_removed.SPECIAL_NEED_TYPE) AND (tbl_added.NUM_CUST = tbl_removed.NUM_CUST)
WHERE (tbl_added.ADDED_REMOVAL_DT < tbl_removed.ADDED_REMOVAL_DT) ;
This keeps the recordset updateable, and still allows you to use a < operator.
In Access SQL you can't join on "<".
You'll have to use a subquery of some kind or create a temp table with those IDs to delete, then join to this.
Edit:
Well, you "can" but not in the GUI designer (see comment from Erik).
So, add the join in the GUI designer the usual way. That will create a join using "=". Then switch to SQL view and change "=" to "<".
It should now run without an error, but you will not be able to switch back to the GUI designer.

Microsoft Access Update Statement with Inner Joins and Subqueries

I am having a tough time figuring out how to do this update query. Basically I need to update a table named tblOpenJobs. It needs to be updated with the dbo_WorkOrders table with the Max Install date. But there is not direct relationship between those two tables you need to have the dbo_premise table between. Here is my query, what am I doing wrong?
UPDATE tblOpenJobs
INNER JOIN (dbo_Premise INNER JOIN dbo_WorkOrders w (WHERE w.InstallDate IN
(SELECT MAX(InstallDate) FROM dbo_WorkOrders WHERE dbo_WorkOrders.PremiseKey = w.PremiseKey))
ON (dbo_Premise.PremiseKey = w.PremiseKey)
ON tblOpenJobs.ServiceOrderNum = dbo_Premise.AccountNumber
SET tblOpenJobs.InstallerID = w.InstallerID,
tblOpenJobs.InstallDate= w.InstallDate,
tblOpenJobs.New_Serial_num= w.NewSerial,
tblOpenJobs.Old_Reading= w.OldRead;
I checked this in Access 2007 query window:
Your query seems neither Transact-SQL, neither Access, as the two have different syntax.
In Access, table aliasing must use the keyword AS, while Transact-SQL does not require:
UPDATE ((tblOpenJobs
INNER JOIN dbo_Premise
ON tblOpenJobs.ServiceOrderNum = dbo_Premise.AccountNumber)
INNER JOIN dbo_WorkOrders AS w
ON dbo_Premise.PremiseKey = w.PremiseKey)
SET tblOpenJobs.InstallerID = w.InstallerID,
tblOpenJobs.InstallDate = w.InstallDate,
tblOpenJobs.New_Serial_num = w.NewSerial,
tblOpenJobs.Old_Reading = w.OldRead
WHERE (w.InstallDate IN
(SELECT MAX(InstallDate)
FROM dbo_WorkOrders
WHERE dbo_WorkOrders.PremiseKey = w.PremiseKey))
This is correct in syntax, but I'm not sure it can update your data, as multi-table linked update is not easy in Access.

Update using Select Statement

I wanna write a query like this :
UPDATE `test_credit`
SET `test_credit`.`credit`=(`test_credit`.`credit`-((`test_credit`.`credit`/100)*5))
WHERE `test_credit`.`name` = `users`.`uname`
in fact i want to get a query on users.uname = test_credit.name but mysql say it has error and realize users.uname as column
what is correct query ?
You need to explicitly join it with table users. As far from my understanding based on your query, you want to calculate the credit if the names exists on both tables.
Give this a try,
UPDATE test_credit a
INNER JOIN users b
ON a.name = b.uname
SET a.credit = (a.credit - ((a.credit/100) * 5.0))
-- WHERE b.parent= "example"

Long time exection in update table with join in SQL server 2008

i'm facing a big problem when trying to update a table containing stock data put in join with a table containing product classification. This operation is taking long time for execution.
Table dw_giacenze (having flag_nomatch parameter equal to T) a is put on inner join with dw_key_prod z on ecat_key field.
a contains up to 3 milions records, z 150k records.
It takes more than 2 hours in execution.
Below the update query I'm using.
update dw_giacenze
set cate_ecat_key = z.cate_ecat_key,
sottocat_ecat_key = z.sottocat_ecat_key,
marchio_key = z.marchio_key,
sottocat_bi_key = z.sottocat_bi_key,
gruppo_bi_key = z.gruppo_bi_key,
famiglia_bi_key = z.famiglia_bi_key,
flag_nomatch = NULL
from dw_giacenze a
inner join dw_key_prod z on
z.ecat_key = a.ecat_key
where
a.flag_nomatch = 'T';
Can anyone help me in optimizing it?
Thanks in advance!
Enrico
I would suggest focusing in on a.flag_nomatch = 'T'.
A great way to get a really clear picture of what's going on is to use SQL Server Profiler. If this shows that your reads equals the number of rows in the table, then that's definitely an issue. Adding an index on flag_nomatch.
Alternatively, you could separate this out and update things individually (to start with)
UPDATE dw_giacenze
set sottocat_ecat_key = (SELECT sottocat_ecat_key
FROM dw_key_prod
WHERE dw_key_prod.ecat_key = dw_giacenze.ecat_key)
where
dw_giacenze.flag_nomatch = 'T';
I did notice that the first parameter in your set statement is actually the same parameter in your join. That means that you are setting it to the same exact value, so you should be able to remove that anyway.