Mysql: Update field of most latest record - mysql

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.

Related

Count number of times, a number appears and update it to a different column

I am not sure how to do this in mysql, i have searched but I can't seem to find a solution.
,
I have a table like so.
id pid occurrence
1 23 blank
2 23 blank
3 44 blank
Basically, occurrence should have the value of 2, for id 1,2 and a value of 1 for id 3.
Any help would be appreciated. I can easily call count and GROUP BY, and get the number of times each one occurance, but I would like to update column occurrence in the right place for each pid.
To get the correct occurrence value you can do
select pid, count(*) as occurrence
from your_table
group by pid
To update the table do
update your_table t1
join
(
select pid, count(*) as occurrence
from your_table
group by pid
) t2 on t1.pid = t2.pid
set t1.occurrence = t2.occurrence
If you want to set the value in the table, use update with a join:
update table t join
(select pid, count(*) as cnt
from table
group by pid
) tt
on tt.pid = t.pid
set t.occurrence = tt.cnt;

Best practice to get newest row in a table

Consider a table like this:
The id column is set to auto-increment, update_time column is supposed to be the date that the row was inserted in the table.
I want to simply get the latest entry for a user with user_id = x, I found out there are some ways:
SELECT * FROM mytable WHERE user_id = x ORDER BY update_time DESC LIMIT 1
And
SELECT * FROM mytable WHERE user_id = x MAX(update_time)
And another query would be selecting the row with highest id number
I am not quite sure about the syntax of the later one (please correct me).
This may seem to be a trivial task, but there was a case that someone else has altered the auto_increment value on the table, and sometimes the time of the server has changed (well this has not been happened in my case but what if it does!!?)
What would be the safest query to get the latest entry row for a user_id ( I mean a query to return weigh, height and activity_level for a user with user_id = x)
Do I need to add more columns to the table? if so, what?
I like the join approach for this. Assumes that userID + update_time is unique...it'll pull back multiple rows if it isn't.
select user_id, max(update_time) maxtime from table group by user_id
Simple statement to get the max update time by user ID. Use it as a subquery with inner join (inner join will function as a filter)
select t.*
from table t
inner join
(select user_id, max(update_time) maxtime
from table group by user_id
--where user_id = x
)a
on a.user_id = t.user_id and a.maxtime = t.update_time
I commented out the where user_id = x line...the advantage to this method is you can get all users and their most recent at once.
SELECT * FROM mytable WHERE user_id = x AND update_time = (SELECT MAX(update_time) FROM mytable WHERE user_id = x)
This really does not have to be so complicated:
SELECT id
FROM table
WHERE user_id = x
ORDER BY update_time DESC
LIMIT 1
This version will be the quickest, simplest, and easiest to read. It is a win in every regard.

UPDATE table using IN and COUNT

I am updating my table setting a field named "status" based on the condition that the total number of distinct rows should be more than 10 and less than 13. The query is as follows:
update myTable set status='Established'
where id IN(select id, count(*) as c
from myTable
where year>=1996 and year<=2008
group by id
having count(distinct year)>=10 and count(distinct year)<=13)
The problem is, I'm getting error1241 that is "operand should contain 1 column"! Could you please advise how can I solve this? Thanks!
The result of the sub query must return only 1 column :
update myTable set status='Established'
where id IN(select id
from myTable
group by id
having count(distinct year)>=10 and count(distinct year)>=13)
In MySQL, an update with a join often performs better than an update with a subquery in the where clause.
This version might have better performance:
update myTable join
(select id, count(*) as c
from myTable
where year >= 1996 and year <= 2008
group by id
having count(distinct year) >= 10 and count(distinct year) <= 13
) filter
on myTable.id = filter.id
set status = 'Established';
I will also note that you have a table where a column called id is not unique among the rows. Typically, such a column would be a primary key, so the having clause would always fail (there would only be one row).
update myTable
set status='Established'
where id IN(select id from myTable
group by id
having count(distinct year)>=10
and count(distinct year)>=13)
You are using IN operator and then you inner query returns two columns id and count(*) it should return only one column back.

MySQL Max statement not returning result

I have the following MySQL statement
SELECT * FROM user_messages AS T WHERE user_id = '33' AND id = (SELECT Max(id) from user_messages AS TT WHERE T.from_userid = TT.from_userid) ORDER BY status, id DESC
The problem I seem to be having is when I only have one record. I would think that MySQL would return the single record associated with user_link = '33', but instead it returns nothing.
I need to use the "Max" function because I use it to pull the most recent entries. I am trying to avoid having multiple queries or having to use php to sort also. Any help much appreciated!
This is your query:
SELECT *
FROM user_messages AS T
WHERE user_id = '33' AND
id = (SELECT Max(id)
from user_messages AS TT
WHERE T.from_userid = TT.from_userid
)
ORDER BY status, id DESC
Here are three reasons it could be failing to return any rows. First, user_id = '33' may not exist in the table. Second from_userid may be NULL. Third, the id value may be NULL for all matching records.
Perhaps this simpler version would help:
select *
from user_messages um
where user_id = '33'
order by id desc
limit 1
Thanks for your answer Gordon, I checked the database, and the record exists. I did some more research, and what it turns out to be is that I needed to join the data. I was able to return the Min or Max record, but the corresponding/related fields weren't returned with it.
SELECT * FROM user_messages INNER JOIN(SELECT from_username, MAX(id) AS id FROM user_messages WHERE user_link = '33' GROUP BY from_username ORDER BY status, id DESC) t2 ON user_messages.id = t2.id AND user_messages.from_username = t2.from_username
The thread that answered the question was this one - Need To Pull Most Recent Record By Timestamp Per Unique ID

Single update last row entry for a set of IDs - 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)