A maneira do Postgres de fazer isso:
SELECT *
FROM 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
-
A palavra-chaveAS
é apenas ruído para aliases de tabela. Mas não o omita dos aliases de coluna. O manual sobre "Omitir a palavra-chave AS":
EmFROM
itens, tanto o padrão quanto o PostgreSQL permitemAS
ser omitido antes de um alias que seja uma palavra-chave não reservada. Mas isso é impraticável para nomes de colunas de saída, devido a ambiguidades sintáticas .
Minha ênfase em negrito.
-
ISNULL()
é uma extensão personalizada do MySQL ou SQL Server. Postgres usa a função padrão SQLCOALESCE()
. Mas você não precisa de nenhum aqui. Use oNULLS LAST
cláusula em vez disso, que é mais rápido e mais limpo. Ver:
- PostgreSQL classifica por datetime asc, null primeiro?
-
Vários usuários terão o mesmo número de amigos. Esses pares seriam classificados arbitrariamente. A execução repetida pode resultar em uma ordem de classificação diferente, o que normalmente não é desejável. Adicione mais expressões aORDER BY
como desempate. Em última análise, a chave primária resolve qualquer ambiguidade restante.
-
Se as duas tabelas compartilharem o mesmo nome de colunauser_id
(como deveriam) você pode usar o atalho de sintaxeUSING
na cláusula de junção. Outro recurso SQL padrão. Efeito colateral de boas-vindas:user_id
é listado apenas uma vez na saída paraSELECT *
, em vez de ao ingressar comON
. Muitos clientes nem aceitariam nomes de coluna duplicados na saída.