MySQL UPDATE query with subquery taking forever - sql

I have a MySQL UPDATE query which takes a long time to complete. Am I missing a much simpler way to achieve the same result?
"UPDATE table2, table1
SET table2.id_occurrences = (SELECT SUM(IF(id = table2.id, 1, 0)) FROM table1)
WHERE table2.id = table1.id;"
table2 contains all possible values of id, exactly one record for each.
table1 contains some values of id, but there are multiple records of some values.
I need to update records in table2 to show the number of occurrences of the corresponding value of id in table1. The above query does the job, but it takes about 3 minutes when table1 contains 500 records, and table2 30,000 records. I have much bigger tables to process so this is too long :)
Thanks in advance.

I think your join on the update is perhaps not necessary...
UPDATE table2
SET table2.id_occurrences = (SELECT COUNT(*) FROM table1
WHERE table2.id = table1.id);

Avoid subqueries, use joins:
UPDATE table2
LEFT JOIN table1 ON (table2.id = table1.id)
SET table2.id_occurrences = COUNT(table1.id)
GROUP BY table2.id
Oh, UPDATE doesn't support GROUP BY. Try this query:
UPDATE table2
LEFT JOIN (
SELECT id, COUNT(*) AS cnt FROM table1 GROUP BY id
) AS t1
ON (table2.id = t1.id)
SET table2.id_occurrences = t1.cnt

I'd go for something like:
UPDATE table2
SET id_occurrences = (SELECT count(*) FROM table1
WHERE table1.id = table2.id)

UPDATE table2, table1
SET table2.id_occurrences = (SELECT SUM(IF(id = table2.id, 1, 0)) FROM table1)
WHERE table2.id in (select distinct table1.id from table1) AND table2.id = table1.id;

Related

Update row in a table based on multiple rows in another table

I have two tables: table1 and table2:
table1 has columns id and integer
table2 has columns id and boolean
table2 can have multiple rows with the same id
I want to update the integer column of table1 by looking at all rows with the same id in table2 and seeing if any of the boolean values are true. If so I want table1.integer to be 1, else I want it to be 0.
I have tried something like this:
UPDATE table1,
(
SELECT table2.id, Sum(table2.boolean) > 0
) AS 'condition'
from table2
WHERE 1
GROUP BY table2.id) table3
SET table1.integer =IF(table3.condition, 1, 0) where table1.id = table3.id
And it seems to work, but I wanted to ask if there is a nicer/cleaner/more succinct way of updating the rows of table1 according to multiple rows of table2.
I would recommend EXISTS:
UPDATE table1 t1
SET t1.integer = (EXISTS (SELECT 1
FROM table2 t2
WHERE t2.id = t.id AND
t2.boolean
)
);
This can take advantage of an index on table2(id, boolean). With such an index, it should be faster than an approach that uses JOIN and AGGREGATION.
The syntax of your query is MySql like, so you can do a join like this:
UPDATE table1 t1 INNER JOIN (
SELECT id, MAX(boolean) maxboolean
FROM table2
GROUP BY id
) t2 ON t2.id = t1.id
SET t1.integer = t2.maxboolean
If there are ids in table1 without a corresponding id in table2 and you want the integer column for them to be updated to 0 then use a LEFT join:
UPDATE table1 t1 LEFT JOIN (
SELECT id, MAX(boolean) maxboolean
FROM table2
GROUP BY id
) t2 ON t2.id = t1.id
SET t1.integer = COALESCE(t2.maxboolean, 0)

How to use count() correlated sub select

I have this SQL query
SELECT table1.*
FROM table1 table1
WHERE table1.table2_id IN (SELECT table2.id
FROM table2
WHERE table2.locked = 0)
I get the result and it works fine, but now I want to count how many rows exist.
I tried something like this:
SELECT table1.count(*)
FROM table1 table1
WHERE table1.table2_id IN (SELECT table2.id
FROM table2
WHERE table2.locked = 0)
But nothing worked…
How can I count the rows in this kind of query?
Try this
SELECT COUNT(*)
FROM table1 table1
WHERE table1.`table2_id` IN (SELECT table2.id FROM table2 WHERE table2.locked = 0)
Hope it will help you! ..

Update table column based on another table based on ID

I have 2 tables 'table1' and 'table2'.
table1 has 10,000 records and table2 has 5,000 records.
Both tables have "RECORD_ID" column. All RECORD_ID's that are in table2 can be found in table1.
I want to UPDATE the "PRICE" column of table1 based on the "RECORD_ID" column of table2.
update table1 set PRICE = table2.PRICE where RECORD_ID = table2.RECORD_ID
I got this error message:
SQL0206N "table2.PRICE" is not valid in the context where it is used
SQLSTATE=42703
I am using DB2.
UPDATE table1 SET table1.price = (SELECT table2.price FROM table2 WHERE table2.record_id = table1.record_id)
Try this:
UPDATE table1 f1
SET f1.price =(
SELECT f2.price
FROM table2 f2
WHERE f2.record_id = f1.record_id
)
WHERE exists
(
SELECT f2.price
FROM table2 f2
WHERE f2.record_id = f1.record_id
)
You have to use a join like this:
UPDATE
Table1
SET
Table1.Column = T2.Column
FROM
Table1 T1
INNER JOIN
Table2 T2
ON
T1.PK = T2.FK;

Select from table with two conditions

I'm stuck with a query and I'd need some help.
I need to select values from a table which meets two conditions from other table, for example:
Select * from table1
where ID = (select ID from table2)
AND value = (select value from table2)
So, if I'd need only one value from the table, I could query:
Select * from table1 where ID = (id1) AND value = (value1)
The only solution that I know is using IN, but it wouldn't be the requested solution.
I need something similar to this, but counting that the data returned by table2 is not only one row, but multiple.
Could somebody give me some clue on how to find this?
Thanks.
One method uses exists:
Select *
from table1 t1
where exists (select 1
from table2 t2
where t2.id = t1.id and t2.value = t1.value
);
This is ANSI standard syntax, so it should work in any database. Some databases support this syntax:
select t1.*
from table1 t1
where (t1.id, t1.value) in (select t2.id, t2.value from table2 t2);
I would use AND and OR
select *
from table1
where (ID = (id1) AND value = (value1))
OR (ID = (id2) AND value = (value2))
Each check must be added in brackets. This allows all results matching the pairs ID and VALUE to be returned.
Select * from
table1 inner join table2 on
(table1.ID = table2.ID and
table1.value = table2.value) ;
Since as far as I can understand , you just need to select every rows from table1 where ID and value in table1 equals ID and value in table2. So you just need inner join which joins table1 and table2 checking the condition.

Losing my table inside of a subquery... what's the issue?

I've got two tables set up, here is a basic example of the setup:
Table1 Table2
____________ ____________
|id |date | |id |stuff |
|_____|______| |_____|______|
so they both have an id column. I'm trying to update table1 in this fashion:
update Table1
set [date] = (select [stuff]
from Table2
where Table2.id = id)
However, in the line where Table2.id = id, it uses the id field from Table2 instead of using the one from Table1.
When I try where Table2.id = Table1.id, I get an error. How can I keep tracking Table1's id per row to use in the subquery for Table2?
You need to reference the id inside the inner query to table 1.
This should solve your problem:
update Table1
set Table1.[date] = (select Table2.[stuff]
from Table2
where Table2.id = Table1.id)
Try this using Join:
Update t1 set t1.[date] = t2.[stuff]
from Table1 t1
join Table2 t2 on t1.id = t2.id
here's the join version,
update a
set a.[date] = b.[stuff]
FROM Table1 a
INNER JOIN Table2 b
ON a.ID = b.ID