SQL Update + Inner Join on a range of rows - mysql

I have table "Temp" and table "Today", with same column names ("url" and "date").
I want to update "date" column of "Temp" table when url match.
But my tables are quite big (30K elements) and phpmyadmin does not want to execute the following - right - query :
update Temp Tp
inner join Today Ty on
Tp.url = Ty.url
set Tp.date = Ty.date
I get a "Query execution was interrupted, error #1317"
Why ? I expect this is because I pay for a mutualized server (OVH) and I am not able to execute queries longer than 2-3 seconds.
Anyway, now I want to execute this query range by range. First 1000 rows, 1000-2000 etc.
I tried the following :
update Temp Tp
inner join
(
select Tp2.date
from Temp Tp2
inner join Today Ty2
on Tp2.url = Ty2.url
limit 1000
) Ty on Tp.url = Ty.url
set Tp.date = Ty.date
BUT I get the following error : #1054 - Unknown column 'Ty.url' in 'on clause'
I couldn't find out why ?

As far as I can see, there are two problems here. First, as already mentioned by #pmbAustin, you're missing a column in your subquery.
Secondly, I think your subquery should be selecting the date from Ty2, rather than Tp2:
update Temp Tp
inner join
(
select Ty2.date, Tp2.url
from Temp Tp2
inner join Today Ty2
on Tp2.url = Ty2.url
limit 1000
) Ty on Tp.url = Ty.url
set Tp.date = Ty.date
See SQLFiddle (although for practical reasons, this demo is limited to 2).
Although you haven't specifically asked this (and you're probably aware already), for completeness it should be mentioned that for subsequent queries, LIMIT should be used alongside OFFSET (or just use the shortcut LIMIT 1000, 1000, LIMIT 2000,1000, LIMIT <offset>, <limit>, etc.

Related

Subquery returns more than one row error when one row is returned

I am currently doing some SQL magic and wanted to update the stock in my companies ERP program. However if I try to run the following query I get the error mentioned in the title.
update llx_product lp
set stock = (select sum(ps.reel)
from llx_product_stock as ps, llx_entrepot as w
where w.entity IN (1)
and w.rowid = ps.fk_entrepot
and ps.fk_product = lp.rowid
group by ps.rowid)
The subquery by itself returns just one row if used with a rowid for the product.
select sum(ps.reel)
from llx_product_stock as ps, llx_entrepot as w
where w.entity in (1)
and w.rowid = ps.fk_entrepot
and ps.fk_product = 7372
group by ps.rowid
Any help would be appreciated
I would suggest writing the query as:
update llx_product lp
set stock = (select sum(ps.reel)
from llx_product_stock ps join
llx_entrepot w
on ps.fk_product = lp.rowid
where w.entity in (1) and
w.rowid = ps.fk_entrepot
);
An aggregation query with no group by cannot return more than one row. It is unclear how your version is returning more than one row because the key used in the group by also has an equality comparison. Perhaps there is some type conversion issue at play.
But in any case, without the group by, you cannot get the error you are currently getting.
For anyone wondering the solution to my issue was a very simple query, Gordon pointed in the right direction and I made it harder than it should be.
update llx_product lp
left join llx_product_stock ps on lp.rowid = ps.fk_product
set lp.stock = ps.reel

Update Query taking long to run

I need some assistance with a query I am using (MySQL) to update another table. When running the nested query, the query runs in less than a second. But as soon as I include the update part, it takes hours to run. The query I am using is as per the below:
UPDATE sys_reference.outlet_reference OUTREF LEFT JOIN
(SELECT
store_code 'storeCode'
, LEFT(header_value,20) 'CoOrds'
FROM
am_data_warehouse.am_headers
WHERE
action_date = CURDATE()- 1
AND header_field_id IN (3641, 4937)
) GPSCO
ON OUTREF.store_code = GPSCO.storeCode
SET OUTREF.gps_coordinates = GPSCO.CoOrds
Below is the structure of the table that is being updated:
I think the sub-query isn't doing you any favors here. I think you can rewrite it to elimiate the sub-query.
UPDATE
sys_reference.outlet_reference AS OUTREF
INNER JOIN am_data_warehouse.am_headers AS GPSCO ON OUTREF.store_code =
GPSCO.storeCode
SET
OUTREF.gps_coordinates = LEFT(GPSCO.header_value,20)
WHERE
GPSCO.action_date = CURDATE() - 1
AND GPSCO.header_field_id IN (3641, 4937)

MySQL Query gets too complex for me

I'm trying to write a MYSQL Query that updates a cell in table1 with information gathered from 2 other tables;
The gathering of data from the other 2 tables goes without much issues (it is slow, but that's because one of the 2 tables has 4601537 records in it.. (because all the rows for one report are split in a separate record, meaning that 1 report has more than 200 records)).
The Query that I use to Join the two tables together is:
# First Table, containing Report_ID's: RE
# Table that has to be updated: REGI
# Join Table: JT
SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100
This returns 100 records (I limit it because the database is in use during work hours and I don't want to steal all resources).
However, I want to use these results in a Query that updates the REGI table (which it uses to select the 100 records in the first place).
However, I get the error that I cannot select from the table itself while updateing it (logically). So I tried selecting the select statement above into a temp table and than Update it; however, then I get the issue that I get to much results (logically! I only need 1 result and get 100) however, I'm getting stuck in my own thougts.. I ultimately need to fill the ReportID into each record of REGI.
I know it should be possible, but I'm no expert in MySQL.. is there anybody that can point me into the right direction?
Ps. fixing the table containing 400k records is not an option, it's a program from an external developer and I can only read that database.
The errors I'm talking about are as follows:
Error Code: 1093. You can't specify target table 'TrialTable' for update in FROM clause
When I use:
UPDATE TrialTable SET TrialTable.BlanccoReport =
(SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100)
WHERE TrialTable.HardwareType="PC" AND TrialTable.BlanccoReport=0)
Then I tried:
UPDATE TrialTable SET TrialTable.BlanccoReport = (SELECT ReportID FROM (<<and the rest of the SQL>>> ) as x WHERE X.SerialNo = TrialTable.Serienummer)
but that gave me the following error:
Error Code: 1242. Subquery returns more than 1 row
Haveing the Query above with a LIMIT 1, gives everything the same result
Firstly, your query seems to be functionally identical to the following:
SELECT RE.report_id ReportID
, REGI.Serienummer SerialNo
FROM Blancco_Registration.TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92
LIMIT 100
So, why not use that?
EDIT:
I still don't get it. I can't see what part of the problem the following fails to solve...
UPDATE TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
SET TrialTable.BlanccoReport = RE.report_id
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92;
(This is not an answer, but maybe a pointer towards a few points that need further attention)
Your JT sub query looks suspicious to me:
(SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92
GROUP BY RE.report_id)
You use group by but don't actually use any aggregate functions. The column RE.Value_string should strictly be something like MAX(RE.Value_string) instead.

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"

how to update one table using data from second table

I am bit stuck with this one.. what i want is update app_name (first table). It returns no error.. but does nothing...
UPDATE tbl_m_app AS tma, tbl_measure AS tm
SET tma.app_name='Ap1'
WHERE (tm.mesure_id = tma.mesure_id
AND tm.live = 1)
This query will do the same work in more obvious way and without joins
UPDATE tbl_m_app AS tma
SET tma.app_name='Ap1'
WHERE tma.mesure_id IN (SELECT tm.mesure_id FROM tbl_measure AS tm WHERE tm.live = 1)
I think this SQL is fine, it's just not matching any rows.
Check this by using a select with the same where clause:
SELECT * FROM tbl_measure tm WHERE tm.live=1;
0 rows returned, right?