SQL ORDER BY

Até agora, as linhas vieram na ordem que o banco quis. Mas a Ana precisa de listas arrumadas: os produtos do mais barato ao mais caro, os clientes em ordem alfabética, os funcionários do maior salário ao menor. Quem arruma é o ORDER BY ("ordenar por", em inglês). Ele vem no fim do SELECT e diz por qual coluna (ou colunas) o resultado deve ser ordenado, e em que sentido.

Você vai aprender
  • Ordenar o resultado por uma coluna, em ordem crescente (ASC) ou decrescente (DESC).
  • Ordenar por várias colunas: primeiro por estado, e dentro de cada estado, por nome.
  • Ordenar pela posição da coluna (ORDER BY 2) e por uma conta (preco * estoque).
  • Onde ficam os valores vazios (NULL) e como mudar isso com NULLS LAST.
  • Por que o SQLite põe "Lápis" depois de "Luvas": a ordem do texto com acentos.
  • Os erros mais comuns, com as mensagens reais do SQLite.

Os exemplos usam o banco da Loja Aurora, e cada quadro "Resultado" é desenhado pelo SQLite de verdade, no seu navegador.


A ideia: arrumar as fichas antes de entregar

Pense de novo nas fichas da loja. O WHERE escolhe quais fichas vão para a mão da Ana. O ORDER BY não tira nem põe ficha nenhuma: ele só arruma a pilha antes de entregar, como quem organiza o fichário em ordem alfabética.

Parte do SELECTPergunta que respondeMuda o número de linhas?
FROMDe qual tabela?—
WHEREQuais linhas?Sim
ORDER BYEm que ordem?Não: as mesmas linhas, só arrumadas
Sem ORDER BY, a ordem é "qualquer uma"

Quando você não usa ORDER BY, o SQLite costuma devolver as linhas na ordem em que estão guardadas, e por isso parece que a tabela "já vem em ordem de id". Mas isso não é garantido: depois de apagar linhas, criar um índice ou trocar de banco, a ordem pode mudar. Se a ordem importa, peça com ORDER BY.


1. O primeiro ORDER BY

Os produtos da Papelaria (categoria 1), do mais barato ao mais caro:

SELECT nome, preco
FROM produtos
WHERE categoria_id = 1
ORDER BY preco;
SELECT nome, preco
As colunas que vão aparecer.
FROM produtos
A tabela.
WHERE categoria_id = 1
Só os 6 produtos da Papelaria.
ORDER BY
"Ordenar por": vem depois do WHERE, no fim da consulta.
preco
A coluna que decide a ordem. Sem mais nada, a ordem é crescente: do menor para o maior.

O Lápis (1.15) veio primeiro e a Mochila (89.99) por último. Repare que as linhas são as mesmas 6 que viriam sem o ORDER BY; só mudou a ordem.


2. Crescente (ASC) e decrescente (DESC)

Para inverter o sentido, escreva DESC depois da coluna:

SELECT nome, preco
FROM produtos
WHERE categoria_id = 1
ORDER BY preco DESC;
PalavraVem deOrdemNúmerosTextoDatas (AAAA-MM-DD)
ASCascending, "subindo"Crescente (é o padrão)1, 2, 3…A, B, C…Da mais antiga à mais nova
DESCdescending, "descendo"Decrescente…3, 2, 1…C, B, ADa mais nova à mais antiga

Como ASC é o padrão, ORDER BY preco e ORDER BY preco ASC são a mesma coisa. Escrever o ASC é opcional; algumas pessoas escrevem para deixar a intenção clara.

Texto também se ordena. Os mesmos produtos, em ordem alfabética:

SELECT nome, preco
FROM produtos
WHERE categoria_id = 1
ORDER BY nome;

E as datas? A Loja Aurora guarda datas no formato AAAA-MM-DD (ano, mês, dia), como 1985-03-12. Nesse formato, a ordem alfabética é igual à ordem do calendário, então ORDER BY nascimento funciona direitinho. Você vai ver isso na seção 6.

Experimente: a lista abaixo mostra os funcionários do menor salário para o maior. Faça a lista começar pelo maior salário.

SELECT nome, cargo, salario
FROM funcionarios
ORDER BY salario;
SELECT nome, cargo, salario
FROM funcionarios
ORDER BY salario DESC;

3. Ordenar por várias colunas

A Ana quer a lista de clientes agrupada por estado e, dentro de cada estado, por cidade e por nome, como uma lista telefônica. Basta pôr as colunas em fila, separadas por vírgula:

SELECT nome, cidade, estado
FROM clientes
ORDER BY estado, cidade, nome;

Leia o ORDER BY da esquerda para a direita, como regras de desempate:

  1. Primeiro, todo mundo é ordenado por estado: CE, PE, PI, SP.
  2. Quem tem o mesmo estado é desempatado pela cidade: no Piauí, Floriano, Oeiras, Parnaíba, Picos, Teresina.
  3. Quem tem o mesmo estado e a mesma cidade é desempatado pelo nome: os 10 clientes de Teresina aparecem em ordem alfabética.

A segunda coluna só é usada quando a primeira empata; a terceira, só quando as duas primeiras empatam.

Cada coluna tem o seu sentido

O ASC ou DESC vale só para a coluna logo antes dele. Os funcionários por cargo (A a Z) e, dentro de cada cargo, do maior salário ao menor:

SELECT nome, cargo, salario
FROM funcionarios
ORDER BY cargo, salario DESC;

O cargo ficou crescente (Estoquista, Gerente, Supervisora, Vendedor, Vendedora) e, entre os três Vendedores, o salário ficou decrescente (3200.5, 3100.0, 2980.9). O DESC não "contaminou" o cargo. Se você quer as duas decrescentes, escreva DESC nas duas: ORDER BY cargo DESC, salario DESC.

A confusão mais comum

Muita gente escreve ORDER BY estado, nome DESC esperando "tudo ao contrário". Não é: o estado continua crescente (CE primeiro), e só os nomes ficam de Z a A dentro de cada estado.


4. Ordenar pela posição da coluna

Em vez do nome da coluna, você pode usar o número dela na lista do SELECT: 1 é a primeira, 2 é a segunda, e assim por diante.

SELECT nome, preco
FROM produtos
WHERE preco > 100
ORDER BY 2 DESC;

Aqui, 2 é o preco (a segunda coluna do SELECT). Os 4 produtos acima de R$ 100 vieram do mais caro (Jogo de Panelas, 249.9) ao mais barato (Faqueiro, 119.4).

É prático para testar uma consulta rapidinho, mas tem um perigo: se alguém mudar a ordem das colunas do SELECT (por exemplo, para SELECT preco, nome), o 2 passa a ser o nome, e a ordem muda sem aviso nenhum. Em consultas que vão ficar guardadas, prefira o nome da coluna.


5. Ordenar por uma conta

O ORDER BY aceita qualquer expressão, não só colunas. A Ana quer saber em quais produtos há mais dinheiro parado no estoque: o preço vezes a quantidade guardada.

SELECT nome, preco, estoque, preco * estoque
FROM produtos
WHERE preco * estoque > 3000
ORDER BY preco * estoque DESC;

O Carregador USB-C nem é caro (45.5), mas com 150 unidades no estoque soma R$ 6.825,00 parados, mais que qualquer outro. A coluna sem nome bonito (preco * estoque) vai ganhar um apelido na aula Apelidos (AS), e aí você poderá escrever ORDER BY com o apelido.

Dá até para ordenar por uma coluna que não aparece no SELECT: SELECT nome FROM produtos ORDER BY preco funciona; o preço decide a ordem, mas não é mostrado.


6. E os valores vazios (NULL)?

Dois clientes não informaram a data de nascimento: o nascimento deles é NULL (vazio). Onde eles ficam quando a lista é ordenada pela data? Veja com os fornecedores, em que os dois estrangeiros não têm estado:

SELECT nome, estado
FROM fornecedores
ORDER BY estado;

No SQLite, o NULL é considerado menor que qualquer valor. Por isso, em ordem crescente, os vazios vêm primeiro; em ordem decrescente, por último. Nem sempre é o que você quer: numa lista de aniversários, é estranho começar por quem não tem data. Para mandar os vazios para o fim, use NULLS LAST ("vazios por último"):

SELECT nome, nascimento
FROM clientes
ORDER BY nascimento NULLS LAST;

Agora a lista começa por Conceição Prado (1965), a cliente mais velha, e Antônio Carlos Neves e Sebastião Moura, sem data, ficaram no fim.

EscritaOnde ficam os NULL no SQLite
ORDER BY coluna (ou ASC)No começo
ORDER BY coluna DESCNo fim
ORDER BY coluna NULLS LASTNo fim, mesmo em ordem crescente
ORDER BY coluna DESC NULLS FIRSTNo começo, mesmo em ordem decrescente

O NULLS FIRST/NULLS LAST vem sempre depois do ASC/DESC. Mais sobre o vazio em O Valor NULL.


7. Texto com acentos: por que "Lápis" vem depois de "Luvas"?

Três produtos que começam com L, em ordem alfabética:

SELECT nome
FROM produtos
WHERE id = 3 OR id = 24 OR id = 45
ORDER BY nome;

Num dicionário, "Lápis" viria antes de "Livro" e de "Luvas". O SQLite pôs por último. Não é defeito, é a regra de comparação padrão dele, chamada BINARY ("binária"): ele compara o código de cada letra no computador, e não a ordem do alfabeto português. Nos códigos:

GrupoExemplosPosição na fila
Algarismos0 1 2 … 9Primeiro
Letras maiúsculas sem acentoA B C … ZDepois dos algarismos
Letras minúsculas sem acentoa b c … zDepois de todas as maiúsculas
Letras com acento (maiúsculas e minúsculas)á, ã, é, ô, Á, É…Depois de tudo isso

Em "Lápis" × "Livro", o L empata; depois vêm "á" e "i". O "i" é uma letra comum e o "á" é uma letra acentuada, que fica no fim da fila. Então "Livro" ganha. Pelo mesmo motivo, um nome em minúsculas, como "ana", viria depois de "Zuleica".

Na prática, para os nomes da Loja Aurora isso quase nunca aparece, porque os acentos estão no meio das palavras e as primeiras letras desempatam antes. Mas fique atento quando a primeira diferença cair numa letra acentuada, como em "Lápis".

E o COLLATE NOCASE?

O SQLite tem outra regra de comparação, a NOCASE ("sem caixa"), que ignora a diferença entre maiúsculas e minúsculas: ORDER BY nome COLLATE NOCASE põe "ana" junto de "Ana". Mas ela só conhece as letras sem acento (de A a Z): "Á" e "á" continuam no fim da fila. O SQLite puro não traz uma ordem "de dicionário" do português; quando isso importa muito, os programas costumam ordenar a lista do lado deles, ou guardar uma coluna extra com o nome sem acentos só para ordenar.


8. Formas diferentes de pedir a mesma ordem

Os funcionários do maior salário para o menor (o salario é a 3ª coluna):

EscritaObservação
ORDER BY salario DESCA mais clara: o nome da coluna e o sentido.
ORDER BY 3 DESCPela posição no SELECT nome, cargo, salario. Quebra se a lista de colunas mudar.
ORDER BY -salarioTruque com números: "menos o salário" em ordem crescente é o salário em ordem decrescente. Funciona, mas confunde quem lê; não use com texto.
SituaçãoQual usar
Consulta que vai ficar guardada num programa ou relatórioO nome da coluna, com ASC/DESC explícito
Teste rápido no terminalA posição (ORDER BY 2) serve
Ordenar por uma contaA conta inteira, ou o apelido dela (aula AS)
A coluna pode ter NULLDecida onde eles ficam: NULLS FIRST ou NULLS LAST
Muitas linhas empatam na primeira colunaAcrescente uma segunda coluna de desempate (um nome, um id)

Quando dá errado

ORDER BY antes do WHERE
SELECT nome, preco
FROM produtos
ORDER BY preco
WHERE preco > 100;

A mensagem: near "WHERE": syntax error, "perto de WHERE: erro de sintaxe". As partes do SELECT têm uma ordem fixa: SELECT → FROM → WHERE → ORDER BY. Depois do ORDER BY, o SQLite não espera mais um WHERE.

Como consertar: o ORDER BY vai sempre por último (só o LIMIT, da próxima aula, vem depois dele).

Esqueceu o BY
SELECT nome, preco FROM produtos ORDER preco;

A mensagem: near "preco": syntax error. O comando é ORDER BY, duas palavras. Sozinho, ORDER não quer dizer nada para o SQL, e ele tropeça na palavra seguinte.

Posição que não existe
SELECT nome, preco FROM produtos ORDER BY 3;

A mensagem: 1st ORDER BY term out of range - should be between 1 and 2, "o 1º termo do ORDER BY está fora do intervalo: deveria estar entre 1 e 2". O SELECT tem só duas colunas, então só existem as posições 1 e 2. O "1st" diz qual item do ORDER BY está errado (o primeiro). O mesmo erro aparece com ORDER BY 0: as posições começam em 1.

Coluna que não existe
SELECT nome, preco FROM produtos ORDER BY valor;

A mensagem: no such column: valor, "não existe a coluna valor". A tabela produtos tem preco, não valor. Confira os nomes em O Banco da Loja Aurora.

ASC e DESC juntos
SELECT nome, preco FROM produtos ORDER BY preco ASC DESC;

A mensagem: near "DESC": syntax error. Cada coluna tem um sentido: ou ASC, ou DESC.

O nome da coluna entre aspas: não dá erro, mas não ordena
SELECT nome
FROM clientes
WHERE estado = 'CE'
ORDER BY 'nome' DESC;

O que aconteceu: nenhuma mensagem, e os nomes vieram fora de ordem (Carlos, Fernanda, Patrícia…, na ordem da tabela). Entre aspas simples, 'nome' não é a coluna: é o texto "nome", igual em todas as linhas. Ordenar por algo que é igual em todas as linhas não muda nada.

Como consertar: nome de coluna vai sem aspas: ORDER BY nome DESC. Aspas simples são só para texto (valores), como 'CE'.

Nos outros bancos

O ORDER BY com ASC, DESC, várias colunas e posição funciona igual em todos os bancos mais usados. A diferença está nos NULL e no texto:

BancoNULL em ORDER BY coluna (crescente)Aceita NULLS FIRST/NULLS LAST?
SQLiteNo começo (o NULL é o menor)Sim
MySQLNo começoNão
SQL ServerNo começo ("o menor valor possível", diz a documentação)Não
PostgreSQLNo fim (o NULL conta como maior que tudo)Sim

Ou seja, a mesma consulta pode trazer os vazios no começo no SQLite e no fim no PostgreSQL. Se o lugar dos NULL importa, escreva NULLS FIRST ou NULLS LAST (onde o banco aceitar).

No texto, MySQL, PostgreSQL e SQL Server usam a collation (regra de ordem e comparação de texto) configurada no banco ou na coluna, que pode conhecer os acentos e as maiúsculas do português. No MySQL 8, por exemplo, a collation padrão do utf8mb4 é utf8mb4_0900_ai_ci, que não diferencia acentos nem maiúsculas. Por isso o "Lápis" desta aula pode aparecer em outro lugar num desses bancos. Ilustrativo (SQL Server, não roda no SQLite):

-- SQL Server: escolhendo a collation só para esta ordenação
SELECT nome FROM produtos ORDER BY nome COLLATE Latin1_General_CI_AI;

Referência rápida

EscritaO que faz
ORDER BY colunaOrdem crescente (o mesmo que ASC)
ORDER BY coluna DESCOrdem decrescente
ORDER BY a, b DESCOrdena por a (crescente); empates são desempatados por b (decrescente)
ORDER BY 2Pela 2ª coluna do SELECT
ORDER BY preco * estoquePor uma conta
ORDER BY coluna NULLS LASTVazios no fim
ORDER BY coluna DESC NULLS FIRSTVazios no começo
ORDER BY nome COLLATE NOCASEIgnora maiúsculas/minúsculas (só de A a Z, sem acentos)
Ordem das partesSELECT → FROM → WHERE → ORDER BY → LIMIT
Mensagem do SQLiteQuer dizer
near "WHERE": syntax errorWHERE depois do ORDER BY
near "preco": syntax errorFaltou o BY (ORDER preco)
1st ORDER BY term out of range - should be between 1 and 2Posição maior que o número de colunas do SELECT (ou 0)
no such column: valorA coluna não existe

Exercícios

1. Do mais caro ao mais barato

Complete a palavra que inverte a ordem:

SELECT nome, preco FROM produtos ORDER BY preco ;

2. As duas palavras

Complete o comando que ordena os clientes por nome:

SELECT nome FROM clientes nome;

3. Em ORDER BY estado, nome DESC, como fica o estado?

4. No SQLite, onde ficam os clientes sem data de nascimento em ORDER BY nascimento?

5. A consulta SELECT nome, preco FROM produtos ORDER BY 3; dá qual resultado?

6. Por que o SQLite põe "Lápis Grafite HB" depois de "Luvas de Jardinagem" em ORDER BY nome?

Missão final: a lista de aniversariantes por estado

Missão: a Ana quer os clientes separados por estado (em ordem crescente: CE, PE, PI, SP) e, dentro de cada estado, do cliente mais novo para o mais velho. Mantenha as três colunas na ordem nome, estado, nascimento e arrume o ORDER BY.

SELECT nome, estado, nascimento
FROM clientes
ORDER BY nascimento;
SELECT nome, estado, nascimento
FROM clientes
ORDER BY estado, nascimento DESC;

Repare nos dois clientes do Piauí sem data (Antônio Carlos e Sebastião): com DESC, eles ficaram no fim do grupo do Piauí. Quer vê-los no começo do grupo? Acrescente NULLS FIRST depois do DESC.


Resumo

  • ORDER BY ("ordenar por") arruma as linhas do resultado; não tira nem acrescenta nenhuma. Sem ele, a ordem não é garantida.
  • Vem depois do WHERE: SELECT → FROM → WHERE → ORDER BY.
  • ASC (crescente) é o padrão; DESC inverte. Cada coluna tem o seu sentido: em ORDER BY a, b DESC, só o b é decrescente.
  • Várias colunas funcionam como desempate, da esquerda para a direita.
  • Também dá para ordenar pela posição (ORDER BY 2) e por uma conta (ORDER BY preco * estoque).
  • No SQLite, o NULL vem primeiro em ordem crescente; use NULLS LAST para mandá-lo para o fim. No PostgreSQL é o contrário.
  • O SQLite ordena texto pelo código das letras: maiúsculas, depois minúsculas, depois acentuadas. Por isso "Lápis" vem depois de "Luvas".