SQL Palavras-chave
As palavras-chave são as palavras que o próprio SQL entende: SELECT, FROM, WHERE, INSERT… Esta página reúne as que aparecem no guia, separadas por assunto, cada uma com o que faz, um exemplo curto e o link para a aula onde ela é explicada com calma. Use-a como um dicionário: quando encontrar uma palavra que não lembra, procure aqui.
- Todo exemplo roda no SQLite 3.50.4 do guia, com o banco da Loja Aurora. Copie para o editor de qualquer aula e clique em Rodar; cada Rodar parte do banco limpo, então os exemplos de
INSERT,UPDATEeDELETEnão estragam nada. - As palavras-chave não ligam para maiúsculas:
SELECTeselectsão a mesma coisa. O costume, seguido no guia, é escrevê-las em MAIÚSCULAS (aula SELECT). - Algumas palavras só funcionam juntas, como
ORDER BYouIS NOT NULL; elas aparecem juntas na tabela.
Atalhos: Consultar · Filtrar e comparar · Juntar tabelas · Combinar consultas · Subconsultas e CASE · Janelas · Mudar dados · Criar tabelas · Regras das colunas · Transações · Ferramentas do SQLite · A ordem das cláusulas
Consultar
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
SELECT | "Selecione": pede dados e diz quais colunas mostrar | SELECT nome FROM categorias; | SELECT |
FROM | "De": a tabela de onde os dados vêm | SELECT * FROM clientes; | SELECT |
DISTINCT | Tira as linhas repetidas do resultado | SELECT DISTINCT cidade FROM clientes; | SELECT DISTINCT |
ALL | Mantém as repetições (o normal, quase nunca escrito) | SELECT ALL cidade FROM clientes; | SELECT DISTINCT |
AS | Dá um apelido a uma coluna ou tabela | SELECT nome AS produto FROM produtos; | Apelidos (AS) |
WHERE | "Onde": filtra as linhas | SELECT nome FROM clientes WHERE estado = 'PI'; | WHERE |
ORDER BY | Ordena as linhas do resultado | SELECT nome, preco FROM produtos ORDER BY preco; | ORDER BY |
ASC / DESC | Ordem crescente (o normal) / decrescente | SELECT nome, preco FROM produtos ORDER BY preco DESC; | ORDER BY |
NULLS FIRST / NULLS LAST | Põe os NULL no começo ou no fim da ordenação | SELECT nome, email FROM clientes ORDER BY email NULLS LAST; | ORDER BY |
LIMIT | Mostra no máximo N linhas | SELECT nome FROM produtos LIMIT 5; | LIMIT e OFFSET |
OFFSET | Pula as primeiras N linhas (usado com LIMIT) | SELECT nome FROM produtos LIMIT 5 OFFSET 10; | LIMIT e OFFSET |
GROUP BY | Junta as linhas em grupos, um por valor | SELECT estado, count(*) FROM clientes GROUP BY estado; | GROUP BY |
HAVING | Filtra os grupos (o WHERE filtra linhas) | SELECT estado, count(*) FROM clientes GROUP BY estado HAVING count(*) > 5; | HAVING |
FILTER | Só as linhas que passam na condição entram numa função agregada | SELECT count(*) FILTER (WHERE vip = 1) FROM clientes; | Funções Agregadas |
Filtrar e comparar
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
AND | "E": todas as condições precisam ser verdadeiras | SELECT nome FROM clientes WHERE estado = 'PI' AND vip = 1; | AND |
OR | "Ou": basta uma condição ser verdadeira | SELECT nome FROM clientes WHERE estado = 'PE' OR estado = 'CE'; | OR |
NOT | Inverte uma condição | SELECT nome FROM clientes WHERE NOT vip = 1; | NOT |
IN | O valor está numa lista | SELECT nome FROM clientes WHERE estado IN ('PE', 'CE'); | IN |
BETWEEN … AND | O valor está numa faixa (as duas pontas incluídas) | SELECT nome FROM produtos WHERE preco BETWEEN 20 AND 30; | BETWEEN |
LIKE | Compara com um padrão de texto | SELECT nome FROM clientes WHERE nome LIKE 'Ana %'; | LIKE |
ESCAPE | Escolhe o caractere que faz % e _ valerem como texto num LIKE | SELECT nome FROM produtos WHERE nome LIKE '%!%%' ESCAPE '!'; | Curingas (% e _) |
GLOB | Padrão de texto no estilo dos arquivos (*, ?), que liga para maiúsculas; só no SQLite | SELECT nome FROM produtos WHERE nome GLOB 'C*'; | Curingas (% e _) |
NULL | "Sem valor" | SELECT NULL; | O Valor NULL |
IS NULL | O campo está vazio | SELECT nome FROM clientes WHERE email IS NULL; | IS NULL e IS NOT NULL |
IS NOT NULL | O campo tem valor | SELECT nome FROM clientes WHERE email IS NOT NULL; | IS NULL e IS NOT NULL |
TRUE / FALSE | Verdadeiro e falso; no SQLite, outros nomes para 1 e 0 | SELECT nome FROM clientes WHERE vip = TRUE; | Tipos de Dados |
COLLATE | Escolhe a regra de comparação de textos; NOCASE ignora maiúsculas (só nas letras sem acento) | SELECT nome FROM clientes WHERE cidade = 'teresina' COLLATE NOCASE; | Funções de Texto |
CAST … AS | Converte um valor para outro tipo | SELECT CAST('42' AS INTEGER); | Os Tipos no SQLite |
Juntar tabelas
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
JOIN / INNER JOIN | Junta as linhas das duas tabelas que combinam | SELECT p.nome, c.nome FROM produtos AS p JOIN categorias AS c ON c.id = p.categoria_id; | INNER JOIN |
ON | A condição que liga as duas tabelas | (no exemplo acima: ON c.id = p.categoria_id) | O que é um JOIN |
USING | Liga pelas colunas que têm o mesmo nome nas duas tabelas | SELECT c.nome, f.nome FROM clientes AS c JOIN fornecedores AS f USING (cidade); | INNER JOIN |
LEFT JOIN | Todas as linhas da tabela da esquerda, com ou sem par | SELECT c.nome, p.id FROM clientes AS c LEFT JOIN pedidos AS p ON p.cliente_id = c.id; | LEFT JOIN |
RIGHT JOIN | Todas as linhas da tabela da direita, com ou sem par | SELECT c.nome, p.id FROM pedidos AS p RIGHT JOIN clientes AS c ON p.cliente_id = c.id; | RIGHT JOIN |
FULL JOIN | Todas as linhas das duas tabelas, com ou sem par | SELECT c.nome, p.id FROM clientes AS c FULL JOIN pedidos AS p ON p.cliente_id = c.id; | FULL JOIN |
CROSS JOIN | Todas as combinações possíveis (cada linha com cada linha) | SELECT c.nome, f.nome FROM categorias AS c CROSS JOIN fornecedores AS f; | O que é um JOIN |
Combinar consultas
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
UNION | Junta os resultados de duas consultas, sem repetições | SELECT cidade FROM clientes UNION SELECT cidade FROM fornecedores; | UNION |
UNION ALL | Junta os resultados, com repetições | SELECT cidade FROM clientes UNION ALL SELECT cidade FROM fornecedores; | UNION ALL |
INTERSECT | Só o que aparece nas duas consultas | SELECT cidade FROM clientes INTERSECT SELECT cidade FROM fornecedores; | UNION |
EXCEPT | O que aparece na primeira e não na segunda | SELECT cidade FROM clientes EXCEPT SELECT cidade FROM fornecedores; | UNION |
Subconsultas, CTE e CASE
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
EXISTS | Verdadeiro se a subconsulta devolve pelo menos uma linha | SELECT nome FROM clientes AS c WHERE EXISTS (SELECT 1 FROM pedidos AS p WHERE p.cliente_id = c.id); | EXISTS |
ANY / SOME / ALL | Compara um valor com uma lista vinda de uma subconsulta. Não existem no SQLite (dão syntax error); a aula mostra o equivalente | — | ANY e ALL |
CASE WHEN … THEN … ELSE … END | Escolhe um valor conforme condições, como um "se… então… senão" | SELECT nome, CASE WHEN preco > 100 THEN 'caro' ELSE 'barato' END FROM produtos; | CASE |
WITH | Dá nome a uma consulta para usar logo em seguida (CTE) | WITH caros AS (SELECT * FROM produtos WHERE preco > 100) SELECT nome FROM caros; | CTE (WITH) |
RECURSIVE | Uma CTE que usa a si mesma, para repetir um passo | WITH RECURSIVE n(x) AS (SELECT 1 UNION ALL SELECT x + 1 FROM n WHERE x < 5) SELECT x FROM n; | CTE Recursiva |
Funções de janela
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
OVER | Calcula uma função olhando um conjunto de linhas, sem juntá-las numa só | SELECT nome, preco, rank() OVER (ORDER BY preco DESC) FROM produtos; | Funções de Janela (OVER) |
PARTITION BY | Divide as linhas da janela em grupos | SELECT nome, categoria_id, rank() OVER (PARTITION BY categoria_id ORDER BY preco DESC) FROM produtos; | PARTITION BY |
Mudar dados
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
INSERT INTO | Acrescenta linhas a uma tabela | INSERT INTO categorias (nome, descricao) VALUES ('Pet', 'Artigos para animais'); | INSERT INTO |
VALUES | Os valores da linha nova (vários grupos = várias linhas) | (no exemplo acima) | Inserindo Várias Linhas |
UPDATE … SET | Muda valores de linhas que já existem | UPDATE produtos SET estoque = 50 WHERE id = 12; | UPDATE |
DELETE FROM | Apaga linhas | DELETE FROM itens_pedido WHERE pedido_id = 90; | DELETE |
RETURNING | Mostra as linhas que o comando inseriu, mudou ou apagou | DELETE FROM itens_pedido WHERE pedido_id = 90 RETURNING produto_id; | DELETE |
INSERT INTO … SELECT | Insere o resultado de uma consulta | INSERT INTO categorias (nome) SELECT 'Cópia de ' || nome FROM categorias WHERE id = 1; | INSERT INTO SELECT |
ON CONFLICT … DO | Diz o que fazer quando o INSERT bate numa chave repetida ("upsert") | INSERT INTO categorias (id, nome, descricao) VALUES (1, 'Papelaria', 'Novo texto') ON CONFLICT (id) DO UPDATE SET descricao = excluded.descricao; | Erros Comuns |
REPLACE INTO | Insere; se a chave já existe, apaga a linha antiga e põe a nova (extensão fora do padrão; existe no SQLite e no MySQL) | REPLACE INTO categorias (id, nome, descricao) VALUES (8, 'Jardim', 'Plantas'); | INSERT INTO |
UPDATE e DELETE sem WHERE
Sem WHERE, o comando vale para todas as linhas da tabela. Veja a aula O Perigo do UPDATE e DELETE sem WHERE antes de usar esses comandos num banco de verdade.
Criar e mudar tabelas
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
CREATE TABLE | Cria uma tabela | CREATE TABLE notas (id INTEGER PRIMARY KEY, texto TEXT NOT NULL); | CREATE TABLE |
IF NOT EXISTS | Só cria se ainda não existir (sem erro se já existe) | CREATE TABLE IF NOT EXISTS notas (id INTEGER PRIMARY KEY, texto TEXT); | CREATE TABLE |
CREATE TABLE … AS | Cria uma tabela com o resultado de uma consulta | CREATE TABLE caros AS SELECT nome, preco FROM produtos WHERE preco > 100; | Criar Tabela a partir de Consulta |
STRICT | Tabela rígida: recusa valores do tipo errado (só no SQLite) | CREATE TABLE medidas (n INTEGER) STRICT; | Os Tipos no SQLite |
ALTER TABLE … ADD COLUMN | Acrescenta uma coluna | ALTER TABLE clientes ADD COLUMN telefone TEXT; | ALTER TABLE |
ALTER TABLE … RENAME | Muda o nome de uma coluna (RENAME COLUMN … TO) ou da tabela (RENAME TO) | ALTER TABLE clientes RENAME COLUMN vip TO cliente_vip; | ALTER TABLE |
DROP TABLE | Apaga a tabela inteira, com os dados | DROP TABLE itens_pedido; | DROP TABLE |
IF EXISTS | Só apaga se existir (sem erro se não existe) | DROP TABLE IF EXISTS rascunho; | DROP TABLE |
CREATE INDEX | Cria um índice, para as buscas ficarem mais rápidas | CREATE INDEX idx_clientes_cidade ON clientes (cidade); | Índices (CREATE INDEX) |
CREATE VIEW | Guarda uma consulta com um nome, para usar como se fosse tabela | CREATE VIEW vips AS SELECT nome FROM clientes WHERE vip = 1; | Views |
Regras das colunas (restrições)
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
PRIMARY KEY | A coluna que identifica cada linha: única e nunca vazia | CREATE TABLE t (id INTEGER PRIMARY KEY, nome TEXT); | PRIMARY KEY |
AUTOINCREMENT | Nunca reaproveita um número de id já usado | CREATE TABLE t (id INTEGER PRIMARY KEY AUTOINCREMENT, nome TEXT); | AUTOINCREMENT |
NOT NULL | A coluna não aceita ficar vazia | CREATE TABLE t (nome TEXT NOT NULL); | NOT NULL |
DEFAULT | O valor usado quando o INSERT não diz nada | CREATE TABLE t (estoque INTEGER DEFAULT 0); | DEFAULT |
UNIQUE | Não deixa dois valores iguais na coluna | CREATE TABLE t (email TEXT UNIQUE); | UNIQUE |
CHECK | Só aceita valores que passam numa condição | CREATE TABLE t (preco REAL CHECK (preco >= 0)); | CHECK |
FOREIGN KEY … REFERENCES | A coluna aponta para o id de outra tabela | CREATE TABLE t (cat INTEGER, FOREIGN KEY (cat) REFERENCES categorias (id)); | FOREIGN KEY |
Transações
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
BEGIN (ou BEGIN TRANSACTION) | Começa uma transação: as mudanças só valem de vez no fim | BEGIN; UPDATE produtos SET estoque = estoque - 1 WHERE id = 2; COMMIT; | Transações (BEGIN e COMMIT) |
COMMIT | Confirma as mudanças da transação | (no exemplo acima) | Transações (BEGIN e COMMIT) |
ROLLBACK | Desfaz as mudanças da transação | BEGIN; UPDATE produtos SET estoque = 0; ROLLBACK; | ROLLBACK e Savepoints |
SAVEPOINT | Marca um ponto dentro da transação, para voltar até ele | SAVEPOINT antes; | ROLLBACK e Savepoints |
ROLLBACK TO | Desfaz só o que veio depois do ponto marcado | ROLLBACK TO antes; | ROLLBACK e Savepoints |
RELEASE | Apaga o ponto marcado (mantendo as mudanças) | RELEASE antes; | ROLLBACK e Savepoints |
Os quatro juntos, numa transação só. O DELETE apaga 2 itens, o ROLLBACK TO os traz de volta, e a contagem final continua 220:
BEGIN; SAVEPOINT antes; DELETE FROM itens_pedido WHERE pedido_id = 90; ROLLBACK TO antes; RELEASE antes; COMMIT; SELECT count(*) FROM itens_pedido;
Ferramentas do SQLite
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
EXPLAIN QUERY PLAN | Mostra como o banco vai procurar os dados (se usa índice ou lê tudo) | EXPLAIN QUERY PLAN SELECT nome FROM clientes WHERE id = 5; | EXPLAIN QUERY PLAN |
PRAGMA | Lê ou muda uma configuração do SQLite | PRAGMA table_info(produtos); | PRAGMAs Úteis |
VACUUM | Reorganiza o arquivo do banco e devolve o espaço que sobrou | VACUUM; | VACUUM e ANALYZE |
ANALYZE | Coleta estatísticas para o banco escolher melhor os índices | ANALYZE; | VACUUM e ANALYZE |
Comandos que começam com ponto, como .tables e .schema, não são palavras-chave do SQL: são comandos do programa sqlite3 e só funcionam no terminal. Eles têm a sua própria referência: Comandos de Ponto do sqlite3.
A ordem das cláusulas num SELECT
As partes de um SELECT têm um lugar fixo. Nenhuma é obrigatória além do SELECT, mas as que aparecerem têm de vir nesta ordem:
| Ordem | Cláusula | Pergunta que responde |
|---|---|---|
| 1 | WITH | Há consultas com nome para usar abaixo? |
| 2 | SELECT (DISTINCT) | Quais colunas mostrar? |
| 3 | FROM (+ JOIN … ON) | De quais tabelas? |
| 4 | WHERE | Quais linhas? |
| 5 | GROUP BY | Agrupar por quê? |
| 6 | HAVING | Quais grupos? |
| 7 | ORDER BY | Em que ordem? |
| 8 | LIMIT (OFFSET) | Quantas linhas, a partir de qual? |
Uma consulta com quase todas elas. Quais estados têm mais de 2 clientes que não são VIP, do maior para o menor, no máximo 3:
SELECT estado, count(*) AS clientes FROM clientes WHERE vip = 0 GROUP BY estado HAVING count(*) > 2 ORDER BY clientes DESC LIMIT 3;
Experimente: mude a consulta: tire o WHERE, troque o DESC por ASC, mude o LIMIT. Veja como cada parte muda o resultado.
SELECT estado, count(*) AS clientes FROM clientes WHERE vip = 0 GROUP BY estado HAVING count(*) > 2 ORDER BY clientes DESC LIMIT 3;
Fora de ordem, vem erro de sintaxe. Aqui o ORDER BY veio antes do GROUP BY:
SELECT estado, count(*) FROM clientes ORDER BY estado GROUP BY estado;
Missão: a consulta quer mostrar quantos clientes há em cada estado, em ordem alfabética de estado, mas as cláusulas estão fora de ordem. Ponha-as no lugar certo.
SELECT estado, count(*) FROM clientes ORDER BY estado GROUP BY estado;
SELECT estado, count(*) FROM clientes GROUP BY estado ORDER BY estado;
Uma coluna com nome de palavra-chave
As palavras-chave são reservadas: o banco as reconhece em qualquer lugar. Se você tentar dar a uma coluna o nome order ("pedido", em inglês, mas também o ORDER de ORDER BY), vem erro:
CREATE TABLE t (order INTEGER);
Entre aspas duplas, que no SQL servem para nomes, a palavra vira um nome comum e funciona:
CREATE TABLE t ("order" INTEGER);
SELECT * FROM t;
Funciona, mas daí em diante você vai ter de escrever "order" com aspas toda vez. O melhor é escolher outro nome: pedido, ordem, posicao. Em português, quase nunca há choque, e esse é um bom motivo para nomear as colunas na nossa língua, como a Loja Aurora faz.
Nos outros bancos
| Palavra | No SQLite do guia | Nos outros |
|---|---|---|
ANY, SOME, ALL (com subconsulta) | Não existem: syntax error | Existem no MySQL, no PostgreSQL e no SQL Server (aula ANY e ALL) |
|| | Junta textos | No MySQL, é um "ou" (obsoleto), a não ser com o modo PIPES_AS_CONCAT (aula OR) |
&& | Não existe: syntax error | No MySQL, é um "e" (obsoleto) (aula AND) |
"texto" | Aspas duplas são nomes: no editor, texto entre aspas duplas dá erro; o sqlite3 do Debian, no terminal, aceita calado se não houver coluna com aquele nome | No MySQL, aspas duplas também podem ser texto, a não ser com o modo ANSI_QUOTES (aula WHERE) |
STRICT, GLOB, PRAGMA | Existem | São só do SQLite |
As outras diferenças entre os bancos (como limitar linhas, criar números automáticos, os tipos de dados) estão em As Diferenças entre os Bancos e em Tipos de Dados.
Resumo
- Palavras-chave são as palavras do próprio SQL. Não ligam para maiúsculas; o costume é escrevê-las em MAIÚSCULAS.
- Consultar:
SELECT,FROM,WHERE,GROUP BY,HAVING,ORDER BY,LIMIT, nessa ordem. - Mudar dados:
INSERT,UPDATE,DELETE. Criar estruturas:CREATE,ALTER,DROP. Transações:BEGIN,COMMIT,ROLLBACK. - Uma palavra-chave não pode ser nome de coluna sem aspas duplas; prefira outro nome.
- Comandos de ponto (
.tables) não são SQL: são do programasqlite3.