Group by and also order by? - mysql

Two tables:
Topics
Comments (There is a Topic field, so I know in which topic the comment is)
And I want to get only the newest comment in each topic (highest value in Date field) and then order the topics in that way.
Query I've tried:
SELECT User, Topic, Date
FROM Comments
GROUP BY Topic
ORDER BY Date DESC

Return a row if no other row with same topic has a later date.
SELECT User, Topic, Date
FROM Comments c1
where not exists (select 1 from Comments c2
where c2.topic = c1.topic
and c2.date > c1.date)
order by date desc

Try this, improved answer:
SELECT `User`,
temp.`Topic`,
temp.`Date`
FROM (
SELECT `Topic`,
MAX(`Date`) `Date`
FROM `Comments`
GROUP BY `Topic`
ORDER BY MAX(`Date`) DESC
) temp
INNER JOIN `Comments`
USING (`Topic`, `Date`)

Related

Select values from table A based on values from table B?

I'm creating a very basic post and reply system to get a better understanding of MySQL and PHP. I have two tables: posts and comments.
posts(post_id, post_user, timestamp, post_text)
comments(comment_id, post_id, timestamp, comment_text)
What I want to do is order the posts by the ones that have the most recent reply. So I would need to SELECT * from posts ordered by comments.timestamp desc since I want to order by most recent comments and not by the original post's timestamp. I can't figure out a proper query that works.
You may looking for this
SELECT p.*
FROM posts p
INNER JOIN comments c ON c.post_id= p.post_id
ORDER BY c.timestamp desc
SELECT post_id, post_user, timestamp, post_text,
most_recent_comment
FROM posts NATURAL JOIN
( SELECT post_id,
MAX( timestamp ) AS most_recent_comment
FROM comments
GROUP
BY post_id ) AS t
UNION
SELECT post_id, post_user, timestamp, post_text,
NULL AS most_recent_comment
FROM posts
WHERE post_id NOT IN ( SELECT post_id FROM comments );
SELECT A.Post_Id FROM
(SELECT P.Post_Id,C.TimeStamp,ROW_NUMBER() OVER( PARTITION BY S.Post_Id ORDER BY C.TimeStamp DESC) Rnk FROM POSTS p INNER JOIN COMMENTS C
ON P.Post_Id=C.Post_Id) A
WHERE A.Rnk=1
ORDER BY A.TimeStamp DESC
This is SQL SERVER version.
So hope you can find Mysql version for it

Select latest post from each categories

Am trying to get the latest post from each category of post ordered by the date, i tried this but its not giving the latest post from the table and when i use 'order by' before 'group by', the post are not ordered by date using mysql.
SELECT post_id, category, author_id, title, article, time FROM (SELECT * FROM blog_post GROUP BY category LIMIT 0,5 ) AS timePost ORDER BY time DESC
SELECT post_id, category, author_id, title, article, time FROM (SELECT * FROM blog_post ORDER BY date LIMIT 0,5 ) AS timePost GROUP BY category
You can do self join.
SELECT T1.`post_id`,
T1.`category`,
T1.`author_id`,
T1.`title`,
T1.`article`,
T1.`time`
FROM
blog_post T1
INNER JOIN
(SELECT MAX(`time`) AS `time`,`category` FROM blog_post GROUP BY category) T2
ON T1.`category` = T2.`category` AND T1.`time` = T2.`time`
ORDER BY T1.`time` DESC
Hope this helps.
IN MS SQL as your question is not clear as per my assumption
SELECT post_id, category, author_id, title, article, time
FROM blog_post t
WHERE
t.post_id=(SELECT TOP 1 post_id
FROM Table t2
WHERE
t.post_id=t2.post_id
ORDER BY time DESC)
This seem to have work... i dont know how efficient it is though
SELECT post_id, category, author_id, title, article, time
FROM (SELECT * FROM blog_post ORDER BY time DESC )
AS timePost GROUP BY category ORDER BY time DESC

MySQL - if row is duplicate, return only the first one

I have a MySQL table "results" which has the following fields:
id (PK, AI), user_id (FK), date, score, time
I want to be able to query this table so that it sorts and returns the fields in order of score (descending order) followed by time (ascending order). So something like:
SELECT * FROM results ORDER BY score DESC, time ASC.
However, after this sorting, if more than one row has the same user_id, I only want to include the highest row.
How would I do this?
You can do this with not exists:
SELECT *
FROM results r
WHERE NOT EXISTS (select 1 from results r2 where r2.user_id = r.user_id and r2.id > r.id)
ORDER BY score DESC;
This will work best with an index on results(user_id, id).
My suggestion: SELECT user_id, max(score), time FROM results GROUP BY user_id ORDER BY score DESC;
Select id and highest score per user_id via max() and Group By. Then order the records by score descending.
EDIT: If you need the time for the user-score and there is only one entry with the same score you can use a subselect to get this time:
SELECT user_id, max(score), (
SELECT max(time)
FROM results AS r2
WHERE r2.user_id = r1.user_id
AND r2.score = max(r1.score)
) AS time
FROM results AS r1
GROUP BY user_id
ORDER BY score DESC;
I've managed to get something working at the moment.
SELECT user_id, score, time
FROM results T
WHERE T.score = (
SELECT MAX(T2.score)
FROM results T2
WHERE T2.user_id = T.user_id
)
ORDER BY score DESC, time ASC;

How do I specify the order of GROUP BY?

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

MySQL Group by UserID only show last post?

I'm trying to show a list with the last posts from each user. If I group by ID however I get the first post instead of the last. How can I group by UID and show only the row with the biggest Date?
This is what I'm trying now:
SELECT * FROM Posts GROUP BY `UID` ORDER BY `Date` DESC
Because you want the largest Date per user, you can use MySQL's MAX():
SELECT MAX(`Date`), * FROM Posts GROUP BY `UID`
You can also specify it in the HAVING clause too:
SELECT *
FROM Posts
GROUP BY `UID`
HAVING `Date` = MAX(`Date`)
ORDER BY `Date` DESC
You can do this using a join, to get the max date, and then only choosing those records:
select p.*
from posts p join
(select uid, max(date) as maxdate
from posts p
group by uid
) pmax
on p.uid = pmax.uid and
p.date = pmax.maxdate