postgreSQL doesn't order by - sql

I have this postgreSQL query, which is supposed to be
returning
top 3 comments ordered by comment_date from
top 10
posts table ordered by post_date...
for some reason it's not ordering by post_date:
with a as
(
SELECT
posts.post_id as post_id
FROM posts where user_id = 'user1'
order by post_date desc --this is not working
limit 10
), b as
(
select user_id,
comment_id,
post_id,
comment_date
, ROW_NUMBER() over (partition by post_id order by comment_date desc) as RowNum
from post_comments
)
SELECT * from a
INNER JOIN b USING (post_id)
where b.RowNum <= 3
example: https://extendsclass.com/postgresql/434e9d2
in the example it should be getting the post which has the highest post_date so like this post3>post2>post1
but the ordering of posts is not working...
I'm new to postgreSQL so i don't have any idea what's happening... actually i got that query from a stackoverflow answer just edited it a little bit: Answer
Thanks for answering and sorry for my bad english

The ordering is just fine. How do I know? The outer query has no order by. Without an order by the results can be in any order.
If you want results in a particular order, then you need to be explicit:
SELECT *
FROM a JOIN
b USING (post_id)
WHERE b.RowNum <= 3
ORDER BY a.post_date DESC;
Note: You'll need to include post_date in the a CTE.

Related

GROUP BY with ORDER BY / last post_time

I have a list of writers in a topic. The List shows the writers name a the last post time inside this topic.
A member can also write more frequently in the topic. Therefore a "group by" was set on the poster_id.
The whole list should be sorted according to the write date. The newest comes first. So I placed maxtime DESC.
Problem:
The list output is working very well but the date of a writer's last post is not the last post_time but always the first post_time.
Table "USERS":
user_id
username
1
Marc
2
Paul
3
Sofie
4
Julia
Table "POSTS"
post_id
topic_id
poster_id
post_time
4565
6
1
999092051
4567
6
4
999094056
4333
6
2
999098058
7644
6
1
999090055
This is my query:
SELECT
p.poster_id,
p.post_time,
p.post_id,
Max(p.post_time) AS maxtime,
u.user_id,
u.username,
FROM POSTS as p
INNER JOIN USERS as u ON u.user_id = p.poster_id
WHERE p.topic_id = 6
GROUP BY p.poster_id
ORDER BY maxtime DESC
How is it possible to display the last post_time of the poster_id instead the first one.
Using columns in Select which are not in group by or in an aggregation function is in most db's forbiden, becuase it is not defined which values are shown.
You can use a subquery with group by and having
SELECT
p.poster_id,
p.post_time,
p.post_id,
p.topic_id,
u.user_id,
u.username
FROM posts as p
INNER JOIN users as u ON u.user_id = p.poster_id
where p.topic_id = 6 AND (p.poster_id, p.post_time )in(select poster_id, max(post_time) from posts group by poster_id )
Demo
The problem with your query is that all your non-aggregated fields must be present inside the GROUP BY clause. As long as this condition is not met, you either have an error fired by your DBMS, or expect some subtle output mistakes. Additionally your query would fire a syntax error due to the comma after the last selected field in the SELECT clause.
If you're using MySQL 8.0, you can use the ROW_NUMBER window function to select your last post time for each poster (rownum = 1, partitioned by poster, ordered by post_time desc), then join back to your users table to get information.
WITH topic_id6 AS (
SELECT poster_id, post_time, post_id, topic_id,
ROW_NUMBER() OVER(PARTITION BY topic_id, poster_id ORDER BY post_time DESC) AS rn
FROM POSTS
)
SELECT id6.poster_id, id6.post_time, id6.post_id, id6.topic_id, u.*
FROM topic_id6 id6
INNER JOIN USERS u
ON id6.poster_id = u.user_id
AND id6.rn = 1
Check the demo here.

How can order by last replies?

I have two tables the first is the 'users' the second is the 'posts',
the 'users' have two columns:
1 id
2 username
the 'posts' have five columns:
1 p_id
2 uid
3 post_id
4 content
5 date
the posts as defined have the value '0' in post_id and the replies have the value p_id in post_id. My query is
SELECT id,username,p_id,uid,post_id,content,date
FROM users
inner join posts
ON users.id=posts.uid
WHERE post_id='0'
ORDER BY p_id DESC
but I want to order by the last replies like in a forum.
Use a correlated subquery in the SELECT clause to find the latest reply date and order by that column. If the post has no replys, use the date of the post instead:
SELECT id,username,p_id,uid,post_id,content,date, (
SELECT MAX(date) FROM posts r WHERE r.post_id = p.p_id
) AS last_reply_date
FROM users
inner join posts p
ON users.id=p.uid
WHERE p.post_id='0'
ORDER BY COALESCE(last_reply_date, p.date) DESC

Selecting top 10 counts in SQLite

I have a table which records questions, their answers, and their authors. The column names are as follows:
id, question, answers, author
I would like to get a list of top 10 authors who have written the most questions. So it would need to first count the number of questions each author has written then sort them by the count then return the top 10.
This is in SQLite and I'm not exactly sure how to get the list of counts. The second part should be fairly simple as it's just an ORDER BY and a LIMIT 10. How can I get the counts into a list which I can select from?
SELECT BY COUNT(author)
,author
FROM table_name
GROUP BY author
ORDER BY COUNT(author) DESC LIMIT 10;
You can apply an order by clause to an aggregate query:
SELECT author, COUNT(*)
FROM mytable
GROUP BY author
ORDER BY 2 DESC
LIMIT 10
You could wrap your query as a subquery and then use LIMIT like this:
SELECT *
FROM (
SELECT author
,COUNT(*) AS cnt
FROM mytable
GROUP BY author
) t
ORDER BY t.cnt DESC
LIMIT 10;

SQL - Order by the numbers of rows?

So I have a table with 5 columns: id, user_id, news_id, comment and date. Every time a user posts something on the news's comment area the data is inserted into this table.
Now I am trying to make a top poster function that will display the people with the mosts comments posted.
I would like to know how to order the result from this table based on how many times that user_id is present in the table.
For example:
1 - 134(user_id) -> 20 posts(that's how many times this user_id was found in the table.)
2 - 123 -> 19
3 - 168 -> 15
and so on.
Thanks in advance.
SELECT user_id, COUNT (*) as comments
FROM table
GROUP BY user_id
ORDER BY comments DESC
TSQL
select userID, count(*)
from userIDtable
group by userID
order by count(*) desc, userID asc
I think you are confusing rows with columns, but never mind. This is easy to do:
SELECT
user_id,
COUNT(*) posts
FROM
comments
GROUP BY
user_id
ORDER BY
posts DESC
SELECT count(user_id) C, user_id FROM RECORDS ORDER BY C LIMIT 5
"So I have a table with 5 rows: id, user_id, news_id, comment and date. Every time a user posts something on the news's comment area the data is inserted into this table. "
In this answer I'll assume you have meant 5 columns above.
select user_id, count(*) num from tableName group by user_id order by num desc;

How do I get 5 latest comments (SQL query for SQL Server ) for each user?

I have a table that looks like this: comment_id, user_id, comment, last_updated.
Comment_id is a key here. Each user may have multiple comments.
How do I get 5 latest comments (SQL query for SQL Server ) for each user?
Output should be similar to the original table, just limit user's comments to 5 most recent for every user.
Assuming at least SQL Server 2005 so you can use the window function (row_number) and the CTE:
;with cteRowNumber as (
select comment_id, user_id, comment, last_updated, ROW_NUMBER() over (partition by user_id order by last_updated desc) as RowNum
from comments
)
select comment_id, user_id, comment, last_updated
from cteRowNumber
where RowNum <= 5
order by user_id, last_updated desc
Joe's answer is the best way to do this in SQL Server (at least, I assume it is, I'm not familiar with CTEs). But here's a solution (not very fast!) using standard SQL:
SELECT * FROM comments c1
WHERE (SELECT COUNT(*) FROM comments c2
WHERE c2.user_id = c1.user_id AND c2.last_updated >= c1.updated) <= 5
In SqlServer 2005, LIMIT is not valid.
Instead, do something like:
SELECT TOP(5) * FROM Comment WHERE user_id = x ORDER BY comment_id ASC
Note that this assumes that comment_id is monotonically increasing, which may not always be a valid assumption for identity fields (if they need to be renumbered for example). You may want to consider an alternate field, but the basic structure would be the same.
Note that if you were ordering by a date field, you would want to sort in descending order rather than ascending order, e.g.
SELECT TOP(5) * FROM Comment WHERE user_id = x ORDER BY last_updated DESC
SELECT TOP 5 * FROM table WHERE user_id = x ORDER BY comment_id ASC
I think that should do it.