Update Inner Join Freeze - mysql

For some reason, this UPDATE query hang forever. If I replace to SELECT - it get the result instantly.
UPDATE table1 AS t1
INNER JOIN
(
SELECT count(*) as total, left(number,7) as prefix, outcome FROM table1
where outcome like '%Passed%'
group by prefix
order by total desc limit 200
) AS t2
ON t2.prefix = left(t1.number,7) AND t1.outcome = 'Fail'
SET t1.outcome = '', t1.status = 'NEW'
What is wrong there?

Try to move the ORDER BY and LIMIt to the end of the UPDATE. Something like:
UPDATE table1 AS t1
INNER JOIN
(
SELECT count(*) as total, left(number,7) as prefix, outcome FROM table1
where outcome like '%Passed%'
group by prefix
) AS t2 ON t2.prefix = left(t1.number, 7) AND t1.outcome = 'Fail'
SET t1.outcome = '', t1.status = 'NEW'
order by total desc
limit 200;
See the syntax of the UPDATE.

I would try something like this:
UPDATE table1
SET
table1.outcome = '',
table1.status = 'NEW'
WHERE
outcome = 'Fail'
AND
left(number,7) IN (SELECT * FROM (
SELECT left(number,7) as prefix
FROM table1
WHERE outcome like '%Passed%'
GROUP BY prefix
ORDER BY COUNT(*) desc limit 200
) s
)
Please see fiddle here.

Can you update the column on which you're joining? That is, t1.outcome.
Move the filter expression t1.outcome = 'Fail' out of the JOIN and in to a WHERE clause.
UPDATE table1 AS t1
INNER JOIN
(
SELECT count(*) as total, left(number,7) as prefix, outcome FROM table1
where outcome like '%Passed%'
group by prefix
order by total desc limit 200
) AS t2
ON t2.prefix = left(t1.number,7)
SET t1.outcome = '', t1.status = 'NEW'
WHERE t1.outcome = 'Fail'

Related

Getting invalid use of group function in update query

Can Someone please help me where is the issue
am getting 'invalid use of group function' in below query
UPDATE t1
JOIN t2 ON t1.id=t2.id
SET t1.total_amount = SUM(IF((t2.`due` <= 0), t2.`amount`, 0))
WHERE t2.flag=1 AND t2.id=003;
You want to aggregate in a subquery, then join and set in the outer query:
update t1
inner join (
select id, sum(case when due < 0 then t2.amount else 0 end) total_amount
from t2
where id = 3 and flag = 1
group by id
) t2 on t1.id = t2.id
set t1.total_amount = t2.total_amount

How to use 'group by' while having a sub query in MySQL?

I have the following query:
SELECT c.text1, sum(c.num1), sum(c.num2), sum(c.num3),
(SELECT count(id) FROM table2 WHERE type = 1 AND txt = c.text1 AND spec_id = c.sp_id)
FROM table1 as c
WHERE c.type = 1
GROUP BY c.text1, c.sp_id
Is there a workaround to loose the c.sp_id from the GroupBy clause somehow? I know that if I remove it MySQL will return an error.
Or is there a way to group the results of this query by c.text1 only?
If I understand the problem correctly, you need to do two separate aggregations. This is one version of the query:
SELECT c.text1, c.sum1, c.sum2, c.sum3, t2.cnt
FROM (SELECT c.text1, sum(c.num1) as sum1, sum(c.num2) as cum2, sum(c.num3) as sum3
FROM table1 c
GROUP BY c.text1
) c LEFT JOIN
(SELECT txt, count(*) as cnt
FROM table2 t2
WHERE t2.type = 1 AND
EXISTS (SELECT 1
FROM table1 c2
WHERE t.txt = c2.txt AND c2.type = 1 AND
t.spec_id = c2.sp_id
)
) t2
ON t2.txt = c.text1
WHERE c.type = 1;

MySQL Update using INNER JOIN with ORDER BY and LIMIT

I'm trying to do an update using an inner join with limit and order by (although the order by is not essential. From what I have read up the standard update will not work... this is what I am trying to do:
UPDATE table1
INNER JOIN table2
ON table1.service_id=table2.service_id
SET table1.flags = NULL
WHERE table1.type = 'fttc'
AND table1.flags = 'co'
AND table2.sync not like '%Yes%'
AND table1.date >= $today_date
ORDER BY table1.priority ASC
LIMIT 20;
it is for use in a case management tool and using php, I want to update 20 tickets i.e. remove the 'flag' so that they can be worked, the quantity will be passed as a variable, so I want to update 20 tickets for example highest 'priority' first, if that can be done?
If I read your question correctly, you want to perform an update on the first 20 records which results from the join, using the priority as ordering. You cannot do this directly in an UPDATE in MySQL AFAIK, but you can create an updatable view and then update that.
CREATE VIEW yourView
AS
SELECT
t1.service_id,
t2.service_id,
t1.flags,
t1.type,
t1.date,
t1.priority,
t2.sync
FROM table1 t1
INNER JOIN table2 t2
ON t1.service_id = t2.service_id
WHERE t1.type = 'fttc' AND
t1.flags = 'co' AND
t2.sync NOT LIKE '%Yes%' AND
t1.date >= $today_date
ORDER BY t1.priority
LIMIT 20;
And then update this view:
UPDATE yourView
SET flags = NULL
There should be no reason to use a view:
UPDATE table1 t1
SET t1.flags = NULL
WHERE t1.type = 'fttc' AND
t1.flags = 'co' AND
t1.date >= $today_date AND
EXISTS (SELECT 1
FROM table2 t2
WHERE t2.service_id = t1.service_id AND
t2.sync not like '%Yes%'
)
ORDER BY t1.priority ASC
LIMIT 20;
You cannot use ORDER BY and LIMIT with a multiple table JOIN. However, you can move the condition on table2 to the WHERE clause.
Following work for me:
UPDATE child AS upd
JOIN (SELECT t1.id FROM child AS t1
INNER JOIN master AS t2
ON t2.id = t1.id
where 1
AND t2.`date` BETWEEN '2020-06-23 00:00:00' AND '2020-06-23 23:59:59'
AND t2.client_id= 10 AND t1.code NOT IN('11','22')
order by t1.id desc LIMIT 1) AS col
ON upd.id=col.id
SET upd.code= '33', upd.`resp` = 'done',upd.status='success'

Sub-query with count(*)

How to get the data that is failed that associate with left(number,7) from sub query count(*) data?
For example I did this:
SELECT * FROM table1 WHERE outcome = 'Fail' AND left(number,7) =
(SELECT count(*) as total, left(number,7) as prefix
FROM table1 where outcome like '%Passed%'
group by prefix order by total desc limit 250)
This wont work because there are two fields in the sub-query.. so how to get around that?
You can use JOIN instead of subquery:
SELECT t1.*, t2.total, ...
FROM table1 AS t1
INNER JOIN
(
SELECT count(*) as total, left(number,7) as prefix
FROM table1
where outcome like '%Passed%' AND outcome = 'Fail'
group by prefix
order by total desc limit 250
) AS t2 ON t2.prefix = left(t1.number,7)
Try this query
SELECT *
FROM
table1 a
INNER JOIN
(SELECT
count(*) as total,
left(number,7) as prefix
FROM
table1
where
outcome like '%Passed%'
group by
prefix
order by
total desc limit 250)b
ON
a.outcome = 'Fail' AND
left(number,7) = b.prefix

UPDATE table with SELECT from another but with a field being SUM(someField)

Basically I have something like this:
UPDATE
Table
SET
Table.col1 = other_table.col1,
FROM
Table
INNER JOIN
other_table
ON
Table.id = other_table.id
The problem is that I would like to update col1 with the select being like:
SELECT SUM(col1) FROM other_table WHERE Table.id = other_table.id AND period > 2011
Edit
Correct Answer:
UPDATE bestall
INNER JOIN (SELECT bestid,SUM(view) as v,SUM(rawView) as rv
FROM beststat
WHERE period > 2011 GROUP BY bestid) as t1
ON bestall.bestid = t1.bestid
SET view = t1.v, rawview = t1.rv
You can't use aggregates directly in a set clause. One way around that is a subquery:
update your_table as yt
left join
(
select id
, count(*) as cnt
from other_table
where period < 4
group by
id
) as ot
on yt.id = ot.id
set col1 = coalesce(ot.cnt,0)
Example at SQL Fiddle.