MySQL - UPDATE statement with INNER JOIN and ORDER BY clause - mysql

I am trying to restore the correct order in one table after certain set of modifications. I need to use UPDATE .. ORDER BY logic, but the field is in another table so INNER JOIN is required. mySQL does not like below syntax, is there any way to accomplish the same ?
SET #newOrder = 0;
UPDATE job T1 INNER JOIN job_schedule T2 ON T1.id = T2.jobID SET T1.order = (#newOrder:=#newOrder+1) WHERE T1.id = 100 ORDER BY T2.scheduledTime ASC
job table:
id actvity order
-------------------------
1 TestEngine 2
2 TestElectricity 1
job_schedule table:
id scheduledTime
-------------------------
1 2022-01-01 10:00:00
2 2022-01-01 11:00:00
After UPDATE, expected results should be:
id actvity order
-------------------------
1 TestEngine 1
2 TestElectricity 2

Related

Mysql Join on Previous Row With Matching Foreign Key

I've got a table, as such:
|id|jobid|statusid| ... other irrelevant rows...
|1 |123 | 1 |
|2 |321 | 2 |
|3 |123 | 2 |
|4 |321 | 3 |
|5 |123 | 3 |
Due to some unfortunate user error, they ended up using (for example) status 3 on some 500 jobs when the policy is to use status 4 following a status 2.
How would I go about joining a row to the previous row matching its value in the column "jobid" when there is an uncertain distance between it and the row before it, given that the value in "statusid" is 3? The goal being to update the table so that any 3 following a 2 with the same jobid (regardless of distance between ids) will be changed to a 4.
My desired output would be to join row 4 and 2 as well as 5 and 3.
(I'm aware the example is consistently id-2, that is not the case in my database.)
So far the relationship would be
SELECT mt.id, mt3.id
FROM mytable mt
INNER JOIN (SELECT MAX(mt1.id) AS mid, mt1.jobid
FROM mytable mt1
WHERE mt1.id < mt.id
GROUP BY mt1.jobid) mt2
ON mt2.jobid = mt.jobid
INNER JOIN mytable tm3
ON mt3.id=mt2.mid
AND mt3.statusid = 2
WHERE mt.statusid=3
But the line in the subquery reading
"WHERE sh1.id < mt.id"
is a relationship that can't exist as mt.id originated outside the subquery.
How can I get this query to work?
Thank you!
You can join to the previous row using a correlated subquery and another join. The following puts the two records on the same row:
select t.*, tprev.*
from (select t.*,
(select t2.id
from mytable t2
where t2.jobid = t.jobid and t2.id < t.id
order by t2.id desc
limit 1
) as prev_id
from mytable t
) t left join
mytable tprev
on t.id = tprev.prev_id;

Removing duplicates by max date

I have a table in my MySQL database that I need to remove the duplicates from.
My table looks something like this:
unique_id value frequency value_type publication_date
1 6.5 1 2 2014-12-31
2 7.5 3 5 2014-06-04
3 6.5 1 2 2015-07-13
4 8.0 4 3 2010-12-31
Rows 1 and 3 are duplicates except for the publication_date. I need to remove these duplicates but keep the row with the max publication date so for this example I would want to remove row 1 and keep row 3.
So far I've tried this but it's giving me too many results on my test table:
SELECT t.* FROM
(SELECT MAX(publication_date) AS most_recent_date
FROM table_1
GROUP BY `value`,frequency,value_type
) t1
JOIN table_1 t
ON t.publication_date = t1.most_recent_date;
Any help would be appreciated.
Thanks.
You can use JOIN to remove the duplicates as
delete t1 from table_1 t1
join table_1 t2 on t1.value = t2.value
and t1.frequency= t2.frequency
and t1.value_type = t2.value_type
and t1.unique_id <> t2.unique_id
and t1.publication_date < t2.publication_date ;

PHP single query Multiple UPDATE effecting AUTO_INCREMENT id instead of order_id

Here is my super-simple table layout...
id | order
1 | 1
2 | 2
I've been trying to update the order for both entries with a single query however my query tests seem to keep updating the auto_increment id field.
My goal is to make id1 = order 2 and id2 = order1 in a single query. What am I doing wrong with my query?
UPDATE forms
SET order = CASE id
WHEN 1 THEN 2
WHEN 2 THEN 1
END
WHERE id IN (1,2);
How about doing JOIN?
UPDATE Tablename AS a
INNER JOIN Tablename AS b
ON a.id = 1 AND b.id = 2
SET a.order = b.order,
b.order = a.order
SQLFiddle Demo

SQL count each distinct value in column and add name from another table where the ID matches

My SQL Skills are next to none. After looking around for the past 2 hours trying to figure this out I need some help please.
I have 2 tables as below
Table1 Table2
ID | Name Status_id
----------- ----------
1 | Open 1
2 | Closed 2
3 | On-Hold 1
What I would like to do is count the status_id in table 2 and group by the status_id. Then add the Name where the ID matches in the first column.
What I have at the moment is
SELECT status_id, COUNT(*) AS 'num' FROM table2 GROUP BY status_id
This is great so far and returns
1 | 2
2 | 1
What I need to return is
Open | 2
Closed | 1
I hope that is clear. Can anyone help?
Many thanks!
SELECT a.name, COUNT(*) AS num FROM table2 b
INNER JOIN table1 a
ON b.status_id=a.id
GROUP BY status_id
In the case that you want to also have Zero for On-Hold you'd need to do a LEFT join and count the a column from table2 instead of *
SELECT t1.name,
Count(t2.Status_id) AS num
FROM table1 t1
LEFT JOIN table2 t2
ON t1.id = t2.Status_id
GROUP BY t1.name;
DEMO

mysql query to identify and delete duplicates based on timestamp

I am trying to build a mysql query to list all column a's that have a duplicate column b from a single table. The trick is I have a timestamp on the rows so i need to essentially identify which is the older of the duplicates so i can delete it. Any help would be appreciated.
Just example - this query return duplicate posts, now you just need to execute delete
id| title | text_desc | created
-------------------------------------------------------
1 | The title | description here |2012-02-21 10:58:58
2 | The title | description here 1 |2012-02-21 10:58:58
3 | The title | description here 3 |2012-02-21 10:58:58
select bad_rows.*
from posts as bad_rows
inner join (
select title, MIN(id) as min_id
from posts
group by title
having count(*) > 1
) as good_rows on good_rows.title = bad_rows.title
and good_rows.min_id <> bad_rows.id;
Here is the return rows
id| title | text_desc | created
-------------------------------------------------------
2 | The title | description here 1 |2012-02-21 10:58:58
3 | The title | description here 3 |2012-02-21 10:58:58
Here's your query:
DELETE FROM tablename
WHERE id IN
(SELECT t1.id
FROM tablename t1
JOIN tablename t2
ON t2.cola = t1.cola AND t2.colb = t1.colb
AND t2.timecol > t1.timecol
WHERE t1.cola = t1.colb)
The SELECT statement returns records where cola = colb and there are other matching rows with a later date. The DELETE statement deletes all records returned by the SELECT.
If you're looking to remove duplicate cola, then this is the query:
DELETE FROM tablename
WHERE id IN
(SELECT t1.id
FROM tablename t1
JOIN tablename t2
ON t2.cola = t1.cola
AND t2.timecol > t1.timecol)
SELECT FOOCODE,COUNT(*) AS DUPS
FROM TABLE
GROUP BY FOOCODE
HAVING COUNT(FOOCODE)>1;
The above query will return u all the duplicates.Is this what u are looking for?