Query to ORDER BY the number of rows returned from another SELECT

风流意气都作罢 提交于 2019-12-17 20:32:48

问题


I'm trying to wrap my head around SQL and I need some help figuring out how to do the following query in PostgreSQL 9.3.

I have a users table, and a friends table that lists user IDs and the user IDs of friends in multiple rows.

I would like to query the user table, and ORDER BY the number of mutual friends in common to a user ID.

So, the friends table would look like:

user_id | friend_user_id
1       | 4
1       | 5
2       | 10
3       | 7

And so on, so user 1 lists 4 and 5 as friends, and user 2 lists 10 as a friend, so I want to sort by the highest count of user 1 in friend_user_id for the result of user_id in the select.


回答1:


The Postgres way to do this:

SELECT *
FORM   users u
LEFT   JOIN (
   SELECT user_id, count(*) AS friends
   FROM   friends
   ) f USING (user_id)
ORDER  BY f.friends DESC NULLS LAST, user_id -- as tiebreaker
  • The keyword AS is just noise for table aliases. But don't omit it from column aliases. I quote the manual on "Omitting the AS Key Word":

    In FROM items, both the standard and PostgreSQL allow AS to be omitted before an alias that is an unreserved keyword. But this is impractical for output column names, because of syntactic ambiguities.

    Bold emphasis mine.

  • ISNULL() is a custom extension of MySQL or SQL Server. Postgres uses the SQL-standard function COALESCE(). But you don't need either here. Use the NULLS LAST clause instead, which is faster and cleaner.

  • It's to be expected that multiple users have the same number of friends. These peers would be sorted arbitrarily. Calling the same function twice might yield different results, which is normally not desirable. Add more expressions to ORDER BY. Ultimately, the primary key resolves any remaining ambiguities.

  • If the two tables share the same column name user_id (like they should) you can use the syntax shortcut USING in the join clause. Another standard SQL feature. Very welcome side effect: user_id is only listed once in the output for SELECT *, as opposed to when joining with ON. Many clients wouldn't even accept duplicate column names in the output.




回答2:


Something like this?

SELECT * FORM [users] u
LEFT JOIN (SELECT user_id, COUNT(*) friends FROM fields) f
ON u.user_id = f.user_id
ORDER BY ISNULL(f.friends,0) DESC


来源:https://stackoverflow.com/questions/20229979/query-to-order-by-the-number-of-rows-returned-from-another-select

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!