Group by with maximum date - mysql

I want to select data from a table, group by this data with the date value maximum.
In my table i have 4 columns - id, message_id, client_id and date. column id is unique and auto incremented, while message_id and client_id have duplicate values. date is almost unique.
I want to select all records, group by message_id and client_id, that has date maximum.
my query is -
SELECT *,MAX(`date`) AS `maxdate` FROM `table_name` group by `message_id`,`client_id` order by `date` desc
but this does not give the date with maximum value.
I am getting the grouped record with first date.
Please help, and tell me the correct query, i am quite new to mysql.

Try this query out - this is how I would do it in Oracle:
select n1.id, n1.message_id, n1.client_id, n1.date
from shailjas_note n1
where n1.date = (select max(n2.date)
from shailjas_note n2
where n1.message_id = n2.message_id
and n1.client_id = n2.client_id)

Related

Distinct on one column but retrieve all

I have got a table with the following syntax:
ID, VALUE, TIMESTAMP
(ID,TIMESTAMP) is primary key, so there might be more than one row for each ID. There are 5000 unique ids.
I want to retrieve the most recent entry for each ID.
My naive way to do was:
SELECT * FROM table ORDER BY TIMESTAMP DESC LIMIT 5000;
For most cases this will give the correct result, but it is not guaranteed.
Because there might be 100k to 500k entries in the Table I would like to take performance into account.
What do you suggest?
TRY THIS
SELECT ID, VALUE, TIMESTAMP
FROM table
GROUP BY ID
HAVING MAX(TIMESTAMP)
ORDER BY TIMESTAMP DESC ;
OR
SELECT ID, VALUE, TIMESTAMP
FROM table
GROUP BY ID
ORDER BY TIMESTAMP DESC ;
Please try this :
SELECT * FROM
(SELECT ID,
VALUE,
ROW_NUMBER() OVER(PARTITION BY ID ORDER BY TIMESTAMP DESC) AS TIMESTAMP
FROM
TABLE )
WHERE TIMESTAMP=1 ;
If your DB supports QUALIFY statement you can try below also :
SELECT * FROM
TABLE
QUALIFY ROW_NUMBER() OVER(PARTITION BY ID ORDER BY TIMESTAMP DESC)=1 ;`enter code here`
You would find the latest date for each ID entry, try this
SELECT *
FROM table AS a
WHERE TIMESTAMP = (
SELECT MAX(TIMESTAMP)
FROM table AS b
WHERE a.ID = b.ID
)

Retrieving last row inserted in table for each "parameter"

I have a table, currently about 1.3M rows which stores measured data points for a couple of different parameters. It is a bout 30 parameters.
Table:
* id
* station_id (int)
* comp_id (int)
* unit_id (int)
* p_id (int)
* timestamp
* value
I have a UNIQUE index on: (station_id, comp_id, unit_id, p_id, timestamp)
Due to timestamp differ for every parameter i have difficulties sorting by the timestamp (I have to use a group by).
So today I select the last value for each parameter by this query:
select p_id, timestamp, value
from (select p_id, timestamp, value
from table
where station_id = 3 and comp_id = 9112 and unit_id = 1 and
p_id in (1,2,3,4,5,6,7,8,9,10)
order by timestamp desc
) table_x
group by p_id;
This query takes about 3 seconds to execute.
Even though i have index as mentioned before the optimizer uses filesort to find the values.
Querying for only 1 specific parameter:
select p_id, timestamp, value from table where station_id = 3 and comp_id = 9112 and unit_id = 1 and p_id =1 order by timestamp desc limit 1;
Takes no time (0.00).
I've also tried joining the parameter-ids to a table which I store the parameter ID's in without luck.
So, is there a simple ( & fast) way to ask for the latest values for a couple of rows with different parameters?
Doing a procedure running a loop asking for each parameter individually seems much faster than asking all for once which I think not is the way to use a database.
Your query is incorrect. You are aggregating by p_id, but including other columns. These come from indeterminate rows, and the documentation is quite clear:
MySQL extends the use of GROUP BY so that the select list can refer to
nonaggregated columns not named in the GROUP BY clause. This means
that the preceding query is legal in MySQL. You can use this feature
to get better performance by avoiding unnecessary column sorting and
grouping. However, this is useful primarily when all values in each
nonaggregated column not named in the GROUP BY are the same for each
group. The server is free to choose any value from each group, so
unless they are the same, the values chosen are indeterminate.
Furthermore, the selection of values from each group cannot be
influenced by adding an ORDER BY clause.
The following should work:
select p_id, timestamp, value
from table t join
(select p_id, max(timestamp) as maxts
from table
where station_id = 3 and comp_id = 9112 and unit_id = 1 and
p_id in (1,2,3,4,5,6,7,8,9,10)
order by timestamp desc
) tt
on tt.pid = t.pid and tt.timestamp = t.maxts;
The best index for this query is a composite index on table(station_id, comp_id, unit_id, p_id, timestamp).

Need to improve sql performance

Table temporary_search_table
post_id,property_status, property_address,....more 30 field
Table search_meta
meta_id,search_id,status,created_date
Ok I need Total data which created_date is yesterday. For each temporary_search_table data there may multiple entry within search_meta. So we need to pick last one field from search_meta and check created date is yesterday and property_status is pending. if yes then we can count the number. If there is no data available in search_meta for entry in temporary_search_table then we dont need to count that row within our results.
Here i am attaching my sql data. its work but for 30000 row it take lots of time.
SELECT COUNT(id) FROM temporary_search_table
WHERE property_status = 'pending' AND (1 = (SELECT DATEDIFF(NOW(), created_date)
FROM search_meta WHERE post_id = search_id ORDER BY created_date DESC LIMIT 0,1 ))
Thanks in advance.
Apart from checking the indexes on your table, it would probably be better to not use a correlated sub query and use a straight join instead.
SELECT COUNT(id)
FROM temporary_search_table
INNER JOIN search_meta ON post_id = search_id
WHERE property_status = 'pending' AND DATEDIFF(NOW(), created_date) = 1
ORDER BY created_date DESC
LIMIT 1

mySQL query to return last record for each table

I have a mySQl db (name "stocks") with 50 tables, each tables with
id, symbol, date, time, open, high, low, close, volume as columns (9 columns).
I would like to know what is the last record for each table, ordered for date then time.
Should I have to ORDER BY all data for each table or there is a better way to just know last record?
I am asking help for a query that just return only last record for each table in db.
Thanks
PS For last record I mean most recent as Date then Time
There are two options how to do that:
-- I would use this only if you need more than one records
SELECT * FROM table ORDER BY date DESC LIMIT 1;
-- Way to go:
SELECT * FROM table WHERE date = (SELECT MAX(date) FROM table) LIMIT 1;
Don't forget to add index on date. If it's possible you add lot's of records at the same time you will have to add:
ORDER BY id DESC -- In case that date is highest for records for last records
ORDER BY time DESC -- Every other case
To the end of query
I am going to make the assumption that the record with the largest ID is the "last" (assuming strictly increasing sequential IDs that are unique within a table). If you have a better definition of "last" that could make a difference.
To get one "last" record, you could do:
Select * from table_1 where id = (select max(id) from table_1);
To get the results of all 50 tables into a single result set, you could do:
Select * from table_1 where id = (select max(id) from table_1)
union
Select * from table_2 where id = (select max(id) from table_2)
union
Select * from table_3 where id = (select max(id) from table_3)
union...
A MySQL-specific solution could be
Select * from table_1 order by id desc limit 1
union
Select * from table_2 order by id desc limit 1
union
Select * from table_3 order by id desc limit 1
union...
Based on your edit (where you actually define what you mean by "last"):
Select * from table_1 order by date desc, time desc, id desc limit 1
union
Select * from table_2 order by date desc, time desc, id desc limit 1
union
Select * from table_3 order by date desc, time desc, id desc limit 1
union...
Here is one way to do it without sorting the table:
select * from tab1
where time = (select max(time)
from tab1
where date = (select max(date) from tab1))
and date = (select max(date) from tab1)
It should be very fast, like, O(c), provided that both columns are indexed, otherwise the time will simply be O(n)

MYSQL query to get records with value that increased most between two dates

I have a MySQL table ScoreArchive with following fields:
ID (int), primary key
Date (date)
Score (int)
I record in the table the Score of each ID every day.
Now I wish to find the IDs that have the top score increase between, for example, 2011-04-22 and 2011-05-31.
How can I find these using a MySQL query?
Try something like:
select id, max(score) - min(score) as diff ... group by id order by diff desc
Edit (following up on the comment):
Or something like:
select id, final_scores.score - start_scores.score as diff
from (
select id, min(date) as min_date, max(date) as max_date
from scores
where date between ...
group by id
) as ranges
join scores as final_scores
on final_scores.date = ranges.min_date
join scores as start_scores
on start_scores.date = ranges.max_date
where ...
order by diff desc
SELECT score FROM ScoreArchive WHERE date BETWEEN 2011-04-22 AND 2011-05-31 ORDER BY score DESC;
That's how i would do it in pgsql i am guessing that mysql is the same