Table :
I am new to query writing. Now I am stuck on retrieving 2 rows from above table.
Data will be date sorted in descending order for only 2 different topic_id. There won't be a third different topic_id.
So I want to retrieve two rows only that will have different topic_id, one data for each topic_id having most recent date.
The result would be
try sql fiddle
http://sqlfiddle.com/#!2/f37963/9
SELECT t1.* FROM temp t1
JOIN (SELECT question_id, MAX(`date`) as `date` FROM temp GROUP BY topic_id) t2
ON t1.question_id= t2.question_id AND t1.`date`= t2.`date`;
The logic is to find the latest date in each group (subquery) and join it with the table again to retrieve other particulars.
use this
$qry="SELECT * FROM table_name GROUP BY TOPIC_ID ORDER BY DATE desc";
Related
I have created a table i.e., table_1 which has different fields. I want to write a query to fetch the latest records from column part_name1 with issue_priority based on time. Column part_name1 may contain same record with different priorities like p1, p2 or p3. Here I have taken less number of records but if I have n number of records how to fetch the latest among the inserted records.
Just an example is given here. Please check out the given image link
**part_name1** **issue_priority** **time1**
blower p1 03:15:00
reverse p2 03:16:18
blower p2 04:11:30
reverse p3 04:44:05
Output: From the above table i want the output to be as mentioned below
blower p2
reverse p3
image link
First, you need to query the latest time for each part_name1. This gives you the maximum time values.
SELECT part_name1, max(time1) as maxtime1
FROM table_1
GROUP BY part_name1;
If you also need the other data in the table (e.g. issue_priority), you should use the above as a subquery:
SELECT t1.*
FROM table_1 t1
JOIN (
SELECT part_name1, max(time1) as maxtime1
FROM table_1
GROUP BY part_name1 ) s1
ON (t1.part_name1 = s1.part_name1 AND t1.time1 = s1.maxtime1);
This will return you the latest row for each part_name1. You can add further LIMIT clause, if you want.
Use max(time1) instead of min(time1) to fetch latest inserted records.
SELECT t1.*
FROM table_1 t1
JOIN (
SELECT part_name1, max(time1) as maxtime1
FROM table_1
GROUP BY part_name1 ) s1
ON (t1.part_name1 = s1.part_name1 AND t1.time1 = s1.maxtime1);
You just need to use ORDER BY :
SELECT fields FROM table ORDER BY time1 DESC LIMIT 2;
In your case, fields is part_name1, table is the name of your table and LIMIT 2 is because you want exactly the last 2 records ( can be set to any number ).
You could use ORDER BY:
SELECT part_name1, issue_priority
FROM table_1
ORDER BY time1 DESC
LIMIT 2
Limit 2 will give you the two most recent records. If you remove the LIMIT then you will get all records ordered by time1 from newest to oldest.
https://dev.mysql.com/doc/refman/8.0/en/order-by-optimization.html
my problem is that I want this:
SELECT * FROM table
WHERE userId = 7243
ORDER BY date desc LIMIT 1
But for multiple ids in one request.
I tried this:
SELECT * FROM table
WHERE userId IN (7243, 1)
GROUP BY userId
ORDER BY date desc
But the order by seems to be ignored. Do anyone has a solution for me? Thank you
If you want the max date record for each of the two IDs, then you may use a subquery:
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
SELECT userId, MAX(date) AS max_date
FROM yourTable
WHERE userId IN (7243, 1)
GROUP BY userId
) t2
ON t1.userId = t2.userId AND t1.date = t2.max_date
WHERE
t1.userId IN (7243, 1);
This is the just greatest-value-per-group question with a slight twist, namely that you only want to see two of the possible groups in the output.
As #Raymond commented below, an index on (userId, date) should greatly speed up the t2 subquery. I am not sure if this index would help beyond that, but it should make a difference.
I often have a situation with two tables in MySQL where I need one record for each foreign key. For example:
table post {id, ...}
table comment {id, post_id, ...}
SELECT * FROM comment GROUP BY post_id ORDER BY id ASC
-- Oldest comment for each post
or
table client {id, ...}
table payment {id, client_id, ...}
SELECT * FROM payment GROUP BY client_id ORDER BY id DESC
-- Most recent payment from each client
These queries often fail because the "SELECT list is not in GROUP BY clause" and contains nonaggregated columns.
Failed Solutions
I can usually work around this with a min()/max() but that creates a very slow query with mis-matched results (row with min(id) isn't equal to row with min(textfield))
SELECT min(id), min(textfield), ... FROM table GROUP BY fk_id
Adding all the columns to GROUP BY results in duplicate records (from the fk_id) which defeats the purpose of GROUP BY.
SELECT id, textfield, ... FROM table GROUP BY fk_id, id, textfield
Same idea as #GurV but using a join instead of a correlated subquery. The basic idea here is that the subquery finds, for each post which has comments, the oldest post and its corresponding id in the comments table. We then join back to comments again to restrict to the records we want.
SELECT t1.*
FROM comments t1
INNER JOIN
(
SELECT post_id, MIN(id) AS min_id
FROM comments
GROUP BY post_id
) t2
ON t1.post_id = t2.post_id AND
t1.id = t2.min_id
You can use a correlated query with aggregation to find out the earliest comment for each post:
select *
from comments c1
where id = (
select min(id)
from comments c2
where c1.post_id = c2.post_id
)
Compound index - comments(id, post_id) should be helpful.
If you are querying the whole table with many rows, then it will. This query is more useful and performant if you are querying for a small subset of posts. If you are querying the whole table, then #Tim's answer is better suited I think.
I have a table with the following columns; id, post_id, status, and datetime. Every time a post(post_id) is updated, a row is inserted with the latest status and datetime timestamp. I am created a pie chart of by status. Therefore I must first SELECT the latest entry of a post (ignoring all past updates), then COUNT how many rows are returned and group by status. What does my query look like?
SELECT status, COUNT(*) AS statusCnt
FROM inspections
WHERE id IN (SELECT MAX(id) FROM inspections GROUP BY post_id)
GROUP BY status
Untested alternative:
SELECT i1.status, COUNT(i1.*) AS statusCnt
FROM inspections i1
JOIN (
SELECT MAX(i2.id) AS maxID FROM inspections i2 GROUP BY i2.post_id
) AS innerTbl ON i1.id = innerTbl.id
GROUP BY i1.status
SELECT count(*) FROM (SELECT *,MAX(time) FROM table GROUP BY post_id) As b
As per my interpretation of your question, query should be like this
How do I ensure, when I GROUP BY QID, that only the most recent row is returned?
ID, QID, VALUE, TIMESTAMP
45,1,Male,1362044759
58,1,Female,1362045122
59,1,Male,1362045149
60,1,Female,1362045153
82,1,Female,1362045863
83,1,Female,1362045887
92,1,Male,1362046012
101,1,Female, 1362046401
SELECT ID, QID, VALUE, TIMESTAMP FROM table GROUP BY ID
...returns the first row. I can't simply do a LIMIT 1, as this is just an example, there are lots of QIDs in the table, which are all grouped.
Thanks.
I'm assuming here you want the "latest" row for each QID. You would normally use a derived-table subquery to get each QID's latest TIMESTAMP value and then join on that:
SELECT ...
FROM myTable AS t
INNER JOIN (SELECT QID, MAX(`TIMESTAMP`) AS MaxT FROM myTable GROUP BY QID) l
ON t.QID = l.QID AND l.maxT = t.`TIMESTAMP`
This is also assuming your TIMESTAMP column increases as time goes on.
If you want the most recent record returned:
SELECT *
FROM TBL
ORDER BY `TIMESTAMP` DESC
LIMIT 1;
Otherwise, if you want to get the most recent record for each group of QID check this Stack Overflow Post that treat your same problem with optimal solutions.
You could use 'GROUP_CONCAT' in order to extract grouped data.
SELECT GROUP_CONCAT(ID ORDER BY TIMESTAMP DESC) AS latest_id