Single update last row entry for a set of IDs - MySQL - mysql

I want to execute an update for a set of Ids in a history table using IN(1,2,3). There is, of course, more than one entry for the same id in the table. For each id, the update should only be performed in the last history entry.
Is there a way to perform this with a single update?
UPDATE table SET fk_something = 123 WHERE id_something IN (1,2,3) AND ...?
Thanks in advance.

If you have a column to determine what the last date is, then you can use an UPDATE with a subquery similar to this:
update yourtable t1
inner join
(
select max(updated_at) MaxDate, id_something
from yourtable
group by id_something
) t2
on t1.id_something = t2.id_something
and t1.updated_at = t2.MaxDate
set t1.fk_something = 123
where t1.id_something IN (1,2,3)
See SQL Fiddle with Demo.
This uses a subquery to get the max(updated_at) value for each id_something. These rows are then joined to your table to make sure that you update the latest row.

Yes:
UPDATE yourtable
SET fk_something = 123
WHERE id_something=1
ORDER BY datecreated DESC
LIMIT 0,1
;
UPDATE yourtable
SET fk_something = 123
WHERE id_something=2
ORDER BY datecreated DESC
LIMIT 0,1
;
...
Just wrap it up in a procedure to simplify. (note you'll need to use prepare/execute if you're passing a CSV list as an argument)

Related

How do I get the rows from sql select to use them afterwards in the same transaction?

Suppose we are doing a SELECT and UPDATE in the same commit in mysql (MariaDB). How can I do:
SELECT id from my_table WHERE mycondition LIMIT 20 FOR UPDATE;
UPDATE my_table SET column1 = 0 WHERE id = the result of the previous select
COMMIT
where id is a primary key auto increment column.
EDIT: I understand that doing like this I would get the result of the SELECT printed, no? At least is what I wanted too, to know which rows I modified
This does not work:
-- UPDATE my_table
-- SET column1 = 0
-- WHERE id in (SELECT id from my_table WHERE mycondition LIMIT 20)
edited:
SELECT #IDS:= GROUP_CONCAT(id)
FROM my_table
WHERE mycondition
LIMIT 20;
UPDATE my_table
SET column1 = 0
where FIND_IN_SET(id,#IDS);
SELECT #IDS;
I would phrase this as a single update join:
UPDATE my_table t1
INNER JOIN
(
SELECT id
FROM my_table
ORDER BY <something>
LIMIT 20
) t2
ON t2.id = t1.id
SET
column1 = 0;
Note that using LIMIT without ORDER BY is fairly undefined and meaningless. If you want to select 20 records using LIMIT, it should be with respect to a certain ordering of your table.

How to update a column for a range of row numbers?

I need to update the column "myColumn" in "myTable" for rows 5 to 10. I thought I can do the following but apparently it's giving me a syntax error:
UPDATE myTable SET myColumn = 'mamal' LIMIT 5,10;
Thanks
SQL tables represent unordered sets. If you have a primary key, you can use that for the ordering.
MySQL does allow limit, but not offset, so you could update the first five rows:
UPDATE myTable
SET myColumn = 'mamal'
ORDER BY id
LIMIT 5;
But not with an offset.
You could get around this with a JOIN:
UPDATE mytable t JOIN
(SELECT id
FROM mytable tt
ORDER BY id
LIMIT 5, 10
) tt
ON tt.id = t.id
SET myColumn = 'mamal';
You can select and update column value based on primarykey of your table.
if you want to change rows limit means you can change limit values.
in below code id Is nothing but Primay Key of your table
UPDATE myTable SET myColumn='mamal' WHERE id IN ( SELECT id FROM ( SELECT id FROM myTable where id ORDER BY id ASC LIMIT 5,5 ) tmp )
TRY by using subquery and join as below and please replace the join column in <column> with real one
UPDATE myTable mt
INNER JOIN (SELECT <column> FROm myTable LIMIT 5,10) t ON t.<column> = mt.<column>
SET mt.myColumn = 'mamal'
Try this:
update myTable
set myColumn = 'mamal'
where your_primary_key
in (select * from (select your_primary_key from myTable limit 5,5) as t);
MySQL does support offset in a limit clause, but only for SELECT. So the correct syntax is: LIMIT offset,row_count. In this case it should be limit 5,5, not limit 5,10. Check: Select Syntax.
You can also use LIMIT in UPDATE, but you can only specify the row_count in this case. Check: Update Syntax.
If you don't have a primary key, just use any unique key.
For why you need a select * from here, it's just a trick to bypass the error discribed here.
I ran into the same problem and saw the answers but after researching I found that you can use "BETWEEN" to UPDATE the Table.
UPDATE myTable
SET myColumn = "mamal"
WHERE id BETWEEN 5 AND 10;

mysql how to update table with same subquery in where clause

Following is my query, I am trying to update recods but I get an error:
you can't specify target table for update in from clause
UPDATE user_payment_info
SET
ammount='110',
status='failed',
transaction_id='0'
WHERE
id=(SELECT id
FROM user_payment_info
WHERE cust_id='771'
ORDER BY id DESC
LIMIT 1)
how can update record with getting id from same table
how can i resolve these mysql error
you can't specify target table for update in from clause
can some body help me to do these.
Try this instead:
UPDATE user_payment_info AS t1
INNER JOIN
(
SELECT MAX(id) AS MaxId
FROM user_payment_info
WHERE cust_id='771'
) AS t2 ON t1.id = t2.MaxId
SET t1.ammount='110',
t1.status='failed',
t1.transaction_id='0';
You don't have to use a subquery, you could use an UPDATE query with order by and LIMIT 1:
UPDATE
user_payment_info
SET
ammount='110',
status='failed',
transaction_id='0'
WHERE
cust_id='771'
ORDER BY
id DESC
LIMIT 1

Mysql: Update field of most latest record

I'm trying to update the latest record where name is John (John has multiple records but different ID) but I seem to be in a bind. What's wrong with my query?
UPDATE messages_tbl SET is_unread=1
WHERE ReceiveTime = (SELECT MAX(ReceiveTime) FROM messages_tbl WHERE name='John')
Is there a better way to do something like this?
You could try using ORDER and LIMIT.
Try this:
UPDATE messages_tbl SET is_unread = 1
WHERE name = 'John'
ORDER BY ReceiveTime DESC
LIMIT 1
This query will update the rows in order of the highest (most recent) ReceiveTime to the lowest (oldest) ReceiveTime. Used in conjunction with LIMIT, only the most recent ReceiveTime will be altered.
You can join both and perform update based on the condition.
UPDATE messages a
INNER JOIN
(
SELECT name , MAX(ReceiveTime) max_time
FROM messages
GROUP BY name
) b ON a.name = b.name AND
a.ReceiveTime = b.max_time
SET a.is_unread = 1
-- WHERE a.name = 'John'
Without the WHERE condition. It will all update the column is_unread for the latest entry.

Confused with UPDATE query. How to convert select to update with MySQL?

I have seen very similar if not same questions on here but my trials of trying to convert following query into an UPDATE statement failed.
SELECT table.* FROM table JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column) WHERE t.rank = 1
ORDER BY t.rank DESC
I want to update column of all results selected using the query above.
How can I convert this into an update statement?
Thank you.
This should do it:
update table
set column = 'somevalue'
where id in
(select id from (
SELECT table.* FROM table JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column) WHERE t.rank = 1) x)
not entirely sure but i think it's something like
update tblname set columname = value where tblname.columncompare = (select statement)
INSERT INTO table (id, value)
SELECT table.id, table.value
FROM table
JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column)
WHERE t.rank = 1
ORDER BY t.rank DESC
ON DUPLICATE KEY UPDATE value = VALUES(value)
Insert on duplicate to the rescue!
Basicly this allows you to do any SELECT as normal and then you prepend INSERT INTO and append ON DUPLICATE.
I guess that this query is made up, but what's the point of filtering and ordering the same column?