- Aprender
- Computação e TI
- Programação
- Noções básicas de SQL
- Consultas com SELECT
Consultas com SELECT
BásicoAula 2 de 6 do curso Curso de Noções básicas de SQL
O que você vai aprender
- Escrever consultas que leem colunas escolhidas de uma tabela, compreender o conjunto de resultados retornado e listar os valores distintos de uma coluna com DISTINCT.
- Escrever uma consulta SELECT básicaIndicar com SELECT as colunas a exibir e com FROM a tabela a ler, seguir as regras básicas de sintaxe e saber como é o resultado.
- Listar valores distintos com DISTINCTRemover linhas repetidas de um resultado com SELECT DISTINCT e prever quantas linhas restam, inclusive quando há várias colunas ou valores ausentes.
- Escrever uma consulta SELECT básica
- Manter apenas as linhas que respondem a uma pergunta, escrevendo condições com operadores de comparação para números, textos e datas e combinando condições com AND, OR e NOT.
- Comparar números com operadores de comparaçãoUsar WHERE com =, <>, <, >, <= e >= para selecionar linhas por valores numéricos e escolher o operador adequado ao enunciado de uma pergunta.
- Comparar textos e datas corretamenteEscrever valores de texto e de data na forma correta, prever como maiúsculas e minúsculas, ordem alfabética e formatos de data afetam uma comparação e evitar erros comuns com aspas e datas.
- Combinar condições com AND, OR e NOTUnir várias condições com AND e OR, inverter uma condição com NOT e usar parênteses para que a consulta teste exatamente o que a pergunta pede.
- Comparar números com operadores de comparação
- Tornar condições mais curtas e precisas com IN para listas de valores, BETWEEN para intervalos e LIKE para padrões de texto, incluindo suas formas com NOT e suas armadilhas comuns.
- Buscar correspondências em uma lista de valores com INUsar IN e NOT IN para manter linhas cujo valor é um dos vários valores listados e saber como listas interagem com AND e com valores ausentes.
- Selecionar um intervalo com BETWEENUsar BETWEEN e NOT BETWEEN para intervalos de números, datas e textos, sabendo que ambos os extremos estão incluídos e onde isso causa erros.
- Buscar padrões de texto com LIKEEncontrar texto que começa ou termina com determinados caracteres ou os contém usando LIKE com % e _, e tratar a diferenciação entre maiúsculas e minúsculas, caracteres curinga literais e valores ausentes.
- Buscar correspondências em uma lista de valores com IN
- Reconhecer NULL como valor ausente, encontrá-lo com IS NULL e IS NOT NULL e prever como valores ausentes alteram o resultado de todos os outros tipos de condição.
- Encontrar valores ausentes com IS NULLDistinguir NULL de zero e de texto vazio e usar IS NULL e IS NOT NULL para encontrar linhas em que um valor está ou não registrado.
- Prever como NULL afeta as condiçõesAplicar a lógica de três valores (verdadeiro, falso, desconhecido) a comparações, AND, OR, NOT, IN, BETWEEN e LIKE e decidir se linhas com valores ausentes pertencem a uma resposta.
- Encontrar valores ausentes com IS NULL
- Colocar as linhas de resultado em uma ordem significativa com ORDER BY, ordenar por várias colunas tratando empates e valores ausentes e retornar as primeiras linhas ou uma página de linhas com LIMIT e OFFSET.
- Ordenar linhas com ORDER BYOrdenar um resultado por uma coluna em ordem crescente ou decrescente e prever como números, datas e textos são ordenados.
- Ordenar por várias colunas e tratar empates e valores NULLOrdenar por mais de uma coluna, com uma direção para cada uma, adicionar critérios de desempate para obter uma ordem reproduzível e controlar onde aparecem os valores ausentes.
- Retornar as primeiras linhas e páginas com LIMIT e OFFSETRetornar as primeiras linhas de um resultado ordenado com LIMIT, pular linhas com OFFSET para mostrar páginas posteriores e escrever a mesma solicitação em outros dialetos SQL.
- Ordenar linhas com ORDER BY
- Combinar todas as cláusulas em consultas corretas e legíveis, compreender a ordem em que uma consulta é processada e transformar perguntas cotidianas em consultas cujos resultados você verifica.
- Colocar as cláusulas em ordem e compreender como uma consulta é executadaEscrever SELECT, FROM, WHERE, ORDER BY e LIMIT na ordem exigida e usar a ordem lógica de processamento para prever o que cada cláusula pode acessar.
- Transformar uma pergunta em uma consulta e verificar a respostaTransformar uma pergunta cotidiana em uma consulta a uma única tabela, passo a passo, e depois verificar limites, valores ausentes, maiúsculas e minúsculas e empates no resultado.
- Colocar as cláusulas em ordem e compreender como uma consulta é executada
Guia de estudo de Consultas com SELECT
1Escolha os dados a exibir
Uma consulta útil começa com a escolha da tabela e das colunas que respondem à sua pergunta. O resultado pode mostrar todos os registros, alguns campos de cada registro ou uma lista de valores distintos. Você trabalhará com duas tabelas pequenas para poder relacionar cada resultado aos dados armazenados. Ler os nomes das colunas com atenção e distinguir a ordem das colunas da ordem das linhas facilitará a compreensão dos filtros e das ordenações a seguir.
1.1 SELECT, FROM e a tabela de resultado
Uma consulta solicita dados a um banco de dados. Uma consulta SELECT simples lê a tabela armazenada sem alterá-la. SELECT indica as colunas a exibir, e FROM indica a tabela a ler.
Os exemplos de texto usam a igualdade comum que diferencia maiúsculas de minúsculas no SQLite e no PostgreSQL. Configurações de colação podem alterar a comparação e a ordenação de texto.
Duas tabelas para trabalhar
A tabela employees tem estas oito linhas. salary é o salário anual em dólares; hire_date é texto no formato YYYY-MM-DD. NULL marca um valor ausente.
| employee_id | first_name | last_name | department | city | salary | hire_date | phone |
|---|---|---|---|---|---|---|---|
| 1 | Ana | Lopez | Sales | Chicago | 52000 | 2019-03-15 | 312-555-0147 |
| 2 | Ben | Carter | IT | Denver | 71000 | 2021-07-01 | NULL |
| 3 | Chloe | Nguyen | Sales | Chicago | 48000 | 2023-01-09 | 312-555-0198 |
| 4 | David | Kim | Marketing | Boston | 60000 | 2020-11-23 | 617-555-0110 |
| 5 | Emma | Brown | Sales | Denver | 65000 | 2018-05-30 | NULL |
| 6 | Farid | Haddad | IT | Chicago | 83000 | 2017-09-12 | 312-555-0175 |
| 7 | Grace | Okafor | NULL | Boston | 45000 | 2024-02-19 | 617-555-0133 |
| 8 | Hugo | O'Neill | Marketing | Chicago | 58000 | 2022-08-05 | NULL |
A tabela products registra preços em dólares e estoque em unidades no depósito.
| product_id | name | category | price | stock |
|---|---|---|---|---|
| 1 | Desk Lamp | Lighting | 24,99 | 40 |
| 2 | Floor Lamp | Lighting | 89,00 | 12 |
| 3 | Lamp Shade | Lighting | 15,50 | 0 |
| 4 | Office Chair | Furniture | 149,00 | 8 |
| 5 | Standing Desk | Furniture | 349,00 | 5 |
| 6 | Desk Organizer | Storage | 18,75 | 60 |
| 7 | Bookshelf | Furniture | 120,00 | NULL |
| 8 | Paper Tray | Storage | 9,99 | 25 |
Leia a estrutura da consulta
SELECT city, first_name
FROM employees;
O conjunto de resultados é outra tabela: oito linhas e duas colunas, com city primeiro. Não há filtro, então cada funcionário contribui com uma linha. A SQL não garante a ordem das linhas até você adicionar ORDER BY.
SELECT * FROM products; exibe todas as colunas na ordem definida pela tabela. O asterisco é útil para explorar. Em uma consulta salva, indicar as colunas mantém o resultado focado e impede que uma coluna recém-adicionada à tabela altere sua estrutura.
Torne a sintaxe legível
Separe as colunas com vírgulas, sem vírgula final antes de FROM. Termine a instrução com ponto e vírgula. As palavras-chave não diferenciam maiúsculas de minúsculas, então select funciona, mas as maiúsculas facilitam a identificação das cláusulas. Espaços e quebras de linha separam palavras; eles não alteram o significado desta consulta. Um comentário com -- continua até o fim da linha.
Os nomes devem corresponder aos do esquema. Se frist_name causar um erro de coluna inexistente, compare a grafia com first_name. A SQL padrão usa aspas duplas para nomes que contêm espaços ou palavras reservadas, como "order date". O PostgreSQL converte nomes sem aspas para minúsculas, enquanto "City" procura esse nome exatamente com a maiúscula. O MySQL normalmente usa crases; aspas duplas identificam nomes no modo ANSI_QUOTES. O SQL Server também aceita colchetes e aceita aspas duplas quando QUOTED_IDENTIFIER está ativado, sua configuração padrão.
Principais conclusões
SELECTescolhe as colunas exibidas;FROMidentifica a tabela delas.- As colunas do resultado seguem a lista SELECT; a ordem das linhas exige
ORDER BY. SELECT *exibe todas as colunas; nomes explícitos mantêm as consultas salvas focadas.- Use vírgulas entre colunas e ponto e vírgula para encerrar uma instrução.
- Confira os nomes no esquema e use as regras do banco de dados para delimitar identificadores com aspas.
1.2 Valores distintos e combinações distintas
Um valor repetido no resultado de uma consulta é frequentemente útil. Vários funcionários podem morar na mesma cidade, e cada um ainda precisa de uma linha. Use DISTINCT quando a pergunta pedir valores ou combinações distintos.
Escolha o que deve contar como duplicata
SELECT DISTINCT city
FROM employees;
O resultado contém Chicago, Denver e Boston, sem ordem garantida. O SELECT city simples retornaria oito linhas porque cada funcionário fornece uma cidade. Adicionar DISTINCT reduz essa exibição a três valores distintos. Isso mantém os oito registros de funcionários armazenados.
A comparação inclui todas as colunas selecionadas. Considere:
SELECT DISTINCT department, city
FROM employees;
Ana e Chloe contribuem com (Sales, Chicago), então esse par aparece uma vez. Emma contribui com (Sales, Denver), que é diferente e permanece. Os outros pares são (IT, Denver), (Marketing, Boston), (IT, Chicago), (NULL, Boston) e (Marketing, Chicago). Há sete linhas de resultado. Departamentos repetidos permanecem porque um departamento associado a outra cidade forma uma linha de resultado diferente.
Escreva DISTINCT uma vez, imediatamente após SELECT. Ele se aplica à linha selecionada inteira. Colocá-lo entre nomes de colunas, como em SELECT department, DISTINCT city, é um erro de sintaxe.
Observe quais colunas você inclui
Se você adicionar employee_id às colunas selecionadas, cada linha se tornará diferente. SELECT DISTINCT employee_id, city FROM employees; ainda retorna oito linhas: cada identificador é único, mesmo quando a cidade se repete. Para responder a “Quais cidades têm funcionários?”, selecione apenas a cidade. Para responder a “Quais funcionários moram em cada cidade?”, mantenha as colunas de identificação e espere cidades repetidas.
Nessa etapa de remoção de duplicatas, valores NULL repetidos são tratados como duplicatas. SELECT DISTINCT department FROM employees; retorna Sales, IT, Marketing e uma linha NULL. A linha NULL registra que um departamento está ausente; ela não é o nome de um quarto departamento. Essa regra de duplicatas difere de NULL = NULL, que resulta em desconhecido em um filtro.
Comparações de texto seguem uma colação, as regras do banco de dados para comparar e ordenar texto. Nas comparações comuns que diferenciam maiúsculas de minúsculas usadas nestes exemplos de SQLite e PostgreSQL, Chicago e chicago são valores diferentes. Uma lista DISTINCT pode revelar uso inconsistente de maiúsculas. Remover repetições da exibição não corrige a grafia nos dados armazenados.
Combine DISTINCT com uma lista curta ordenada
SELECT DISTINCT city
FROM employees
ORDER BY city
LIMIT 2;
Primeiro, as cidades duplicadas desaparecem. Em seguida, as três cidades são ordenadas. Por fim, restam duas linhas de resultado: Boston e Chicago, nessa ordem. Aplicar o limite primeiro às linhas de funcionários responderia a outra pergunta.
Em uma consulta DISTINCT, mantenha as colunas de ordenação na lista SELECT. O PostgreSQL exige isso; o SQLite permite algumas consultas que ordenam por uma coluna não selecionada, mas a escolha entre diferentes valores ocultos torna a ordenação difícil de interpretar. Se um resultado tiver repetições inesperadas, examine as colunas selecionadas antes de decidir que DISTINCT deve fazer parte da consulta.
Principais conclusões
DISTINCTremove linhas completas duplicadas do resultado sem alterar as linhas armazenadas.- Adicionar colunas altera quais linhas contam como duplicatas; uma chave única mantém todas as linhas distintas.
- DISTINCT agrupa valores NULL repetidos.
- As duplicatas são removidas antes de o resultado ordenado ser limitado.
2Mantenha as linhas que respondem à pergunta
A filtragem transforma uma tabela em uma resposta sobre registros específicos: uma faixa salarial, uma cidade ou um grupo que atende a várias condições. Pequenas escolhas importam, inclusive se um extremo conta e se duas condições devem ser atendidas ao mesmo tempo. Comparações numéricas, valores de texto e de data e lógica agrupada têm suas próprias regras. Uma consulta pode ser executada com sucesso e ainda assim fazer a pergunta errada, então você acompanhará quais linhas passam em cada teste.
2.1 Números e valores de fronteira
A cláusula WHERE mantém uma linha somente quando sua condição é verdadeira. Ela vem depois de FROM e pode testar qualquer coluna da tabela, inclusive uma coluna que você não exibe.
Relacione as palavras ao operador
| Solicitação | Operador | Exemplo de condição |
|---|---|---|
| Igual a | = | stock = 0 |
| Diferente de | <> | stock <> 0 |
| Mais de | > | salary > 60000 |
| Pelo menos | >= | salary >= 60000 |
| Menos de | < | price < 20.50 |
| No máximo | <= | price <= 20.50 |
<> é a forma da SQL padrão para “diferente de”. Os cinco bancos de dados discutidos aqui também aceitam !=. Use um sinal de igualdade para indicar igualdade. O SQLite aceita ==, mas o PostgreSQL rejeita essa forma.
Acompanhe uma linha no limite
SELECT first_name, salary
FROM employees
WHERE salary > 60000;
Ben ganha 71000, Emma ganha 65000 e Farid ganha 83000. Essas são as três linhas que atendem à condição, sem ordem determinada. David ganha exatamente 60000. Sua linha não passa em > 60000 porque “mais de” exclui a igualdade.
Altere apenas o operador para >=. David agora entra no resultado, que passa a ter quatro linhas. É assim que “pelo menos 60000” difere de “mais de 60000”. Uma verificação útil do limite pergunta o que acontece com um valor exatamente igual ao limite; valores muito acima dele não revelam esse erro.
Para “no máximo 20,50”, um preço de 20,50 passa e um preço de 20,51 não passa. Quando uma solicitação fornece um limite inferior e um superior, verifique cada extremo separadamente antes de unir os testes.
Escreva valores numéricos como números
Use apenas algarismos em condições SQL: 60000, sem separador de milhares ou símbolo de moeda. Uma vírgula separa itens em SQL; WHERE salary > 60,000 é um erro de sintaxe. Valores decimais usam ponto, como em WHERE price < 20.50. Salários e preços pertencem a colunas numéricas para que as comparações usem sua magnitude numérica.
Texto que parece numérico segue regras de texto quando comparado como texto. O valor de texto '9' é ordenado depois de '10' porque seu primeiro caractere vem depois. Isso informa sobre caracteres, não sobre nove ser maior que dez. Leia o tipo de dados da coluna antes de interpretar uma comparação inesperada.
Filtre sem exibir a coluna testada
SELECT first_name
FROM employees
WHERE salary < 50000;
Chloe e Grace passam. Seus salários são usados para testar as linhas, mas não aparecem no resultado. Você não precisa adicionar o salário a SELECT para que o filtro funcione. Ao verificar uma consulta, exibi-lo temporariamente pode ajudar você a examinar por que cada linha passou.
Uma igualdade em uma chave primária permite buscar diretamente um registro: WHERE employee_id = 6 encontra Farid. Uma chave primária identifica uma linha, então essa igualdade não pode retornar vários funcionários com o mesmo identificador.
Dados ausentes exigem cuidado separado. WHERE stock <> 0 retorna seis produtos. Lamp Shade fica de fora porque seu estoque conhecido é zero. Bookshelf também fica de fora: seu estoque é NULL, então a comparação é desconhecida e WHERE não o mantém. Um teste de “diferente de” não acrescenta valores ausentes ao resultado.
Principais conclusões
- WHERE mantém apenas as linhas cuja condição é verdadeira.
>e<excluem seus limites;>=e<=os incluem.- Escreva literais numéricos sem símbolos de moeda, aspas ou separadores de milhares.
- Um filtro pode testar uma coluna que não é exibida.
- Use uma igualdade em uma chave para buscar um registro.
- Comparações comuns com NULL não passam por um filtro WHERE.
2.2 Texto, aspas e datas completas
Condições de texto e de data precisam de valores em uma forma que o banco de dados possa interpretar. Um valor escrito incorretamente pode não retornar nenhuma linha sem gerar aviso, enquanto a falta de aspas pode transformar esse valor em um nome de coluna.
Distinga um valor de um nome
SELECT first_name
FROM employees
WHERE city = 'Chicago';
As aspas simples tornam 'Chicago' um valor de texto. O resultado contém Ana, Chloe, Farid e Hugo. Sem aspas, Chicago é interpretado como um nome, então o banco de dados procura uma coluna com esse nome. As aspas duplas padrão também delimitam nomes. O PostgreSQL rejeita city = "Chicago" quando essa coluna não existe. Algumas configurações do SQLite aceitam cadeias entre aspas duplas como recurso legado; use aspas simples para valores de forma consistente.
Um apóstrofo dentro de um valor é duplicado:
SELECT first_name
FROM employees
WHERE last_name = 'O''Neill';
Isso encontra Hugo. As duas aspas simples adjacentes representam um apóstrofo dentro do valor; as aspas externas marcam seu início e seu fim. A SQL padrão não usa uma barra invertida para escapar esse apóstrofo.
Verifique as regras de comparação
Uma colação controla a igualdade e a ordenação de texto, incluindo maiúsculas, minúsculas e letras acentuadas. Nas comparações comuns que diferenciam maiúsculas de minúsculas no SQLite e no PostgreSQL usadas aqui, 'Chicago' e 'chicago' são diferentes. WHERE city = 'chicago' não retorna linhas. MySQL e SQL Server costumam usar colações que ignoram maiúsculas e minúsculas, então suas configurações usuais podem encontrar ambas as grafias.
Comparações de intervalos de texto também seguem a colação. Com esses nomes, WHERE last_name < 'M' retorna Brown, Carter, Haddad, Kim e Lopez. Os valores são comparados a partir da esquerda. Um valor mais longo que começa com os mesmos caracteres vem depois de seu prefixo: 'Martin' vem depois de 'M'. Um limite de 'M' não é o mesmo que “todos os nomes que começam com M”.
Coloque o ano primeiro
A coluna hire_date do exemplo armazena datas completas como texto: ano, mês e depois dia, com larguras fixas. Isso faz com que a ordem do texto corresponda à ordem do calendário.
SELECT first_name, hire_date
FROM employees
WHERE hire_date >= '2022-01-01';
Chloe, Grace e Hugo passam. O PostgreSQL também tem um tipo DATE para datas reais que aceita esse literal. Sua forma padrão com tipo explícito é DATE '2022-01-01'; o SQLite não usa essa sintaxe de literal tipado.
Uma data em texto no formato local, como '03/04/2024', é ambígua em uma coluna de data porque as configurações podem interpretá-la como 4 de março ou 3 de abril. Armazenadas como texto, datas com o mês primeiro são comparadas pelo mês antes do ano. Por exemplo, '12/01/2021' é ordenado depois de '03/15/2024', embora a primeira data no calendário seja anterior.
Interprete o limite com a data completa
“Contratado após 2022” significa a partir de '2023-01-01'. Comparar o texto com '2022' também inclui o '2022-08-05' de Hugo: o texto mais longo é ordenado depois do prefixo correspondente.
Se uma coluna contiver horas, a igualdade com apenas uma data não seleciona todas as horas desse dia. Para incluir 31 de março de 2024, use ordered_at >= '2024-03-31' AND ordered_at < '2024-04-01'. Isso mantém todos os horários desde o início de 31 de março até o início de 1º de abril, sem incluí-lo.
Principais conclusões
- Use aspas simples para valores de texto; duplique um apóstrofo dentro de um valor.
- A colação determina como maiúsculas, minúsculas e caracteres de texto são comparados.
- Use datas
YYYY-MM-DDcompletas para que datas de texto com largura fixa sejam ordenadas cronologicamente. - Para cobrir um dia inteiro com horas, inclua seu início e exclua o início do dia seguinte.
2.3 AND, OR, NOT e condições agrupadas
Uma linha pode precisar passar em vários testes. AND exige que ambas as condições sejam verdadeiras. OR exige que pelo menos uma seja verdadeira. NOT inverte verdadeiro e falso; quando uma condição é desconhecida por causa de NULL, NOT a mantém desconhecida.
Decida se ambos os testes devem ser atendidos
SELECT first_name
FROM employees
WHERE department = 'Sales' AND city = 'Chicago';
Ana e Chloe passam nos dois testes. Emma trabalha em Sales, mas mora em Denver, então não passa nesse AND. Mudar AND para OR também inclui Emma, Farid e Hugo: os cinco funcionários que atendem à condição satisfazem um teste ou ambos.
Adicionar uma condição AND pode manter ou reduzir o resultado. Adicionar uma condição OR pode manter ou ampliar o resultado. Isso permite uma verificação rápida ao construir um filtro em etapas.
Toda comparação deve estar completa. Escreva department = 'IT' OR department = 'Marketing', repetindo a coluna e o operador. department = 'IT' OR 'Marketing' não expressa a segunda comparação. O PostgreSQL a rejeita; o SQLite trata o texto isolado como falso e retorna apenas funcionários de IT. Da mesma forma, escreva salary > 50000 AND salary < 70000, com salary dos dois lados de AND.
Interprete grupos de alternativas
“Funcionários em Boston e Denver” normalmente pede pessoas em qualquer uma das duas cidades. Cada linha tem uma cidade, então use city = 'Boston' OR city = 'Denver'. Isso retorna Ben, David, Emma e Grace. Um AND entre essas igualdades exige que um único valor de cidade seja os dois lugares ao mesmo tempo e não retorna linhas.
Quando operadores são combinados, NOT é avaliado antes de AND, e AND antes de OR. Sem parênteses:
WHERE department = 'Sales'
OR department = 'Marketing' AND city = 'Chicago'
Isso significa funcionários de Sales em qualquer lugar, mais funcionários de Marketing em Chicago. Emma passa porque a comparação com Sales é suficiente. Para restringir ambos os departamentos a Chicago, agrupe as alternativas:
SELECT first_name
FROM employees
WHERE (department = 'Sales' OR department = 'Marketing')
AND city = 'Chicago';
Agora Ana, Chloe e Hugo passam. Os parênteses submetem as duas opções de departamento a uma mesma exigência de cidade. Use-os para tornar claro um filtro que mistura AND e OR, mesmo quando a ordem padrão já estaria correta.
Inverta um grupo inteiro
NOT (city = 'Chicago' OR city = 'Denver') retorna David e Grace em Boston. Nenhuma das cidades listadas é permitida. Isso equivale a city <> 'Chicago' AND city <> 'Denver' para esses valores.
Usar OR entre esses dois testes de “diferente de” é uma armadilha comum. Uma linha de Chicago é diferente de Denver, e uma linha de Denver é diferente de Chicago. Todo funcionário com uma cidade registrada passa em pelo menos um teste, então o OR não exclui nenhuma das duas cidades.
Construa uma condição complexa por partes. Verifique as linhas depois do primeiro teste e depois de adicionar o seguinte. Você pode trocar os dois lados de um AND ou os dois lados de um OR sem alterar a resposta; escolha a disposição que torne os grupos mais fáceis de ler.
Principais conclusões
- AND exige ambas as condições; OR exige pelo menos uma.
- Escreva uma comparação completa de cada lado de um operador lógico.
- NOT é avaliado antes de AND e depois OR; parênteses explicitam o agrupamento pretendido.
- Alternativas para uma coluna geralmente precisam de OR, mesmo quando a solicitação diz “e”.
- Para excluir ambas as correspondências, negue o grupo com OR ou una as duas exclusões com AND.
3Busque correspondências em listas, intervalos e padrões de texto
Algumas perguntas pedem várias opções exatas, outras pedem uma faixa de valores ou parte de um nome. IN, BETWEEN e LIKE dão uma forma clara a cada tipo de solicitação. A escolha entre eles começa pelo significado de uma correspondência: um valor inteiro, um valor entre extremos ou um texto que se ajusta a um padrão. Você também verificará valores ausentes e detalhes que alteram uma resposta, incluindo a inclusão dos extremos, a posição dos caracteres curinga e a diferenciação entre maiúsculas e minúsculas.
3.1 Listas de opções exatas com IN
Use IN quando uma coluna puder corresponder a qualquer valor de uma lista. Ele encurta um grupo de igualdades unidas por OR, mantendo seu significado.
Crie uma lista de alternativas
SELECT first_name
FROM employees
WHERE department IN ('IT', 'Marketing');
Ben, David, Farid e Hugo passam. Cada um tem um dos dois valores de departamento. O mesmo teste poderia ser escrito como department = 'IT' OR department = 'Marketing'.
Coloque os itens da lista entre parênteses, separados por vírgulas. Coloque texto entre aspas; deixe valores numéricos sem aspas. Por exemplo, employee_id IN (2, 4, 6) seleciona Ben, David e Farid. A ordem dos itens da lista não ordena o resultado. Repetir um item não repete uma linha correspondente: IN (6, 2, 2, 4) seleciona os mesmos registros. Use ORDER BY se precisar de uma ordem para o resultado.
IN busca correspondências de valores inteiros segundo as mesmas regras de comparação da igualdade. city IN ('Chi') não corresponde a Chicago. Nas comparações comuns que diferenciam maiúsculas de minúsculas usadas aqui, city IN ('chicago') também não corresponde. Uma busca por fragmento precisa de LIKE, enquanto o tratamento de maiúsculas e minúsculas depende da colação.
Aplique outra regra a todas as opções
SELECT first_name
FROM employees
WHERE department IN ('IT', 'Marketing')
AND city = 'Chicago';
Farid e Hugo passam. IN é uma condição, então AND aplica o teste de cidade a toda a escolha de departamentos. Na versão expandida com OR, coloque parênteses em torno das duas comparações de departamento. Sem eles, department = 'IT' OR department = 'Marketing' AND city = 'Chicago' também inclui Ben, pois AND tem precedência maior e a regra de cidade se aplica apenas a Marketing.
Exclua os valores listados
WHERE city NOT IN ('Chicago', 'Denver') retorna David e Grace. Uma cidade registrada passa somente quando é diferente das duas entradas. Essa é uma forma útil para várias exclusões e evita o erro de unir condições de “diferente de” com OR.
Valores ausentes não correspondem a nenhuma das duas formas. Grace tem departamento NULL, então department NOT IN ('Sales') não a inclui. O banco de dados não consegue determinar que o departamento ausente é diferente de Sales. Para incluir também funcionários sem departamento atribuído, escreva department NOT IN ('Sales') OR department IS NULL.
Um NULL dentro de uma lista NOT IN cria um problema mais amplo. department NOT IN ('Sales', NULL) exige tanto department <> 'Sales' quanto department <> NULL. A segunda comparação é sempre desconhecida, então o teste combinado nunca é verdadeiro e WHERE não retorna linhas. Mantenha os testes de valores ausentes separados da lista de valores.
Com IN, uma correspondência real ainda passa mesmo que outro item da lista seja NULL. department IN ('Sales', NULL) mantém os três funcionários de Sales, mas não adiciona Grace. Use IS NULL para solicitar explicitamente valores ausentes.
Uma lista IN comum em SQL precisa de pelo menos um item. O PostgreSQL rejeita IN (); o SQLite o aceita como falso. Se um programa criar uma lista a partir das escolhas do usuário, trate uma lista vazia antes de enviar a consulta para que o comportamento seja intencional nos diferentes bancos de dados.
Principais conclusões
- IN encontra correspondência com qualquer valor inteiro em sua lista entre parênteses, separada por vírgulas.
- A ordem da lista e as entradas repetidas não controlam a ordem do resultado nem duplicam as linhas correspondentes.
- IN se combina com AND como uma única condição.
- NOT IN exclui os valores listados, mas não inclui valores ausentes.
- Um NULL dentro de uma lista NOT IN impede que qualquer linha passe pelo teste WHERE.
3.2 Intervalos e extremos incluídos
BETWEEN testa um intervalo com ambos os extremos incluídos. Use-o quando “de” e “até” incluírem os valores de fronteira indicados; use comparações explícitas quando algum limite precisar ser excluído.
Verifique os dois extremos
SELECT name, price
FROM products
WHERE price BETWEEN 15.50 AND 89.00;
Desk Lamp, Floor Lamp, Lamp Shade e Desk Organizer passam. Floor Lamp custa exatamente 89,00 e Lamp Shade exatamente 15,50, então ambos permanecem. A condição significa price >= 15.50 AND price <= 89.00.
Coloque o menor valor primeiro. price BETWEEN 89.00 AND 15.50 pede um preço de pelo menos 89,00 e no máximo 15,50. É uma sintaxe válida, mas não há correspondências. O BETWEEN comum não reordena os extremos para você. O PostgreSQL oferece BETWEEN SYMMETRIC para fazer isso, mas use a forma com o menor valor primeiro para uma consulta compartilhada com o SQLite.
Para “mais de 15,50 e menos de 89,00”, escreva price > 15.50 AND price < 89.00. Apenas Desk Lamp e Desk Organizer passam. Essa diferença diz respeito aos extremos da pergunta, não à forma como o resultado é exibido.
Fora de um intervalo
price NOT BETWEEN 20 AND 100 significa price < 20 OR price > 100. Ele retorna Lamp Shade, Office Chair, Standing Desk, Desk Organizer, Bookshelf e Paper Tray. Valores exatamente iguais a 20 ou 100 estariam dentro do intervalo original e não passariam em NOT BETWEEN.
Um valor testado ausente resulta em desconhecido em qualquer um dos dois testes. Para estoque, BETWEEN 5 AND 40 seleciona cinco produtos e NOT BETWEEN seleciona dois: Lamp Shade com 0 e Desk Organizer com 60. Bookshelf tem estoque NULL e não pertence a nenhum dos resultados. Portanto, um intervalo e sua negação não precisam abranger todas as linhas armazenadas.
Datas e horas
Datas completas em texto na ordem YYYY-MM-DD permitem usar intervalos de datas. hire_date BETWEEN '2020-01-01' AND '2022-12-31' seleciona Ben, David e Hugo, abrangendo os três anos do calendário nessa coluna que contém apenas datas.
Uma coluna que contém horas precisa de um limite superior diferente para um mês inteiro. Um extremo que contém apenas a data em uma coluna de data e hora significa meia-noite no início desse dia. Como texto, até '2024-03-31 00:00:00' é ordenado depois do prefixo mais curto '2024-03-31'. Para incluir todos os horários de março, use:
WHERE ordered_at >= '2024-03-01'
AND ordered_at < '2024-04-01'
Isso inclui o início de março e termina imediatamente antes de abril, sem precisar adivinhar a última fração de segundo de 31 de março.
Intervalos de texto e os dois usos de AND
Extremos de texto são valores completos. last_name BETWEEN 'A' AND 'C' inclui Brown, mas exclui Carter, pois Carter é ordenado depois de seu prefixo C. Segundo essas regras de texto, last_name >= 'A' AND last_name < 'D' abrange nomes que começam com A, B ou C e retorna Brown e Carter.
Em price BETWEEN 10 AND 100 AND category = 'Lighting', o primeiro AND separa os extremos do intervalo; o segundo une o teste do intervalo ao teste da categoria. Os produtos correspondentes são Desk Lamp, Floor Lamp e Lamp Shade. Quebras de linha podem facilitar a visualização dos dois papéis.
Principais conclusões
- BETWEEN inclui ambos os extremos e espera o extremo inferior primeiro.
- NOT BETWEEN seleciona valores abaixo do extremo inferior ou acima do extremo superior.
- Comparações explícitas permitem excluir um ou ambos os extremos.
- Para um mês inteiro com horas, inclua seu início e termine antes do mês seguinte.
- Um extremo de texto é um valor inteiro, não todos os valores com aquela letra inicial.
- NULL na coluna testada não passa em nenhum dos dois testes de intervalo.
3.3 Padrões de texto com LIKE
LIKE testa um texto em relação a um padrão. Use-o para buscar um início, um final ou um fragmento quando a igualdade exigiria um valor inteiro exato.
Posicione os caracteres curinga
| Padrão | Significado | Nomes de produtos correspondentes |
|---|---|---|
'Lamp%' | Começa com Lamp | Lamp Shade |
'%Lamp' | Termina com Lamp | Desk Lamp, Floor Lamp |
'%Lamp%' | Contém Lamp | Desk Lamp, Floor Lamp, Lamp Shade |
'Lamp' | Exatamente Lamp | Nenhum |
O padrão deve corresponder ao valor inteiro. % pode representar zero ou mais caracteres, incluindo espaços. Em '%Lamp%', qualquer um dos sinais de porcentagem pode corresponder a nenhum caractere, então o texto pode começar ou terminar com Lamp, além de contê-lo no meio.
_ representa exatamente um caractere. last_name LIKE '_im' encontra Kim. Quatro sublinhados em first_name LIKE '____' encontram Emma e Hugo, os nomes com exatamente quatro letras. O sublinhado não é um caractere opcional.
SELECT first_name, phone
FROM employees
WHERE phone LIKE '312-%';
Ana, Chloe e Farid passam porque o texto de telefone registrado começa com 312-. O sinal de porcentagem abrange todos os caracteres restantes.
Escolha o operador e a regra de maiúsculas e minúsculas
Caracteres curinga pertencem a padrões LIKE. name = '%Lamp%' procura sinais de porcentagem literais e não retorna produtos aqui. Os caracteres curinga de busca de arquivos * e ? não têm significado especial em LIKE; name LIKE 'Desk*' procura um asterisco literal depois de Desk.
O LIKE do SQLite normalmente ignora maiúsculas e minúsculas para as letras ASCII de A a Z, enquanto o LIKE comum do PostgreSQL as diferencia. Assim, name LIKE '%desk%' encontra Desk Lamp, Standing Desk e Desk Organizer no SQLite, mas nenhum no PostgreSQL com uma colação que diferencia maiúsculas de minúsculas. O PostgreSQL também oferece ILIKE, que ignora essa diferença. O comportamento do MySQL segue a colação.
Para os nomes de produtos ASCII usados aqui, LOWER(name) LIKE '%desk%' fornece as mesmas correspondências no SQLite e no PostgreSQL: LOWER converte o nome para minúsculas antes da comparação. A conversão entre maiúsculas e minúsculas em outros sistemas de escrita depende das regras do banco de dados e do idioma. A igualdade no SQLite também difere de seu LIKE: city = 'chicago' não encontra Chicago com a colação binária padrão, embora city LIKE 'chicago' o encontre.
Busque um caractere curinga literal
Para encontrar um sublinhado literal, escolha um caractere de escape:
WHERE code LIKE 'SPRING!_%' ESCAPE '!'
Em uma tabela de códigos de desconto, isso corresponde a 'SPRING_10', mas não a 'SPRINGS10'. O !_ é um sublinhado real; o último % continua correspondendo a uma sequência. Use a mesma abordagem com !% para um sinal de porcentagem literal. Escrever ESCAPE explicitamente evita depender dos padrões do banco de dados; o PostgreSQL normalmente usa uma barra invertida e o SQLite não tem caractere de escape padrão.
Negação e tamanho da busca
name NOT LIKE '%Lamp%' retorna os outros cinco produtos. Texto ausente não passa nem em LIKE nem em NOT LIKE. Entre os funcionários, três telefones correspondem a '312-%', dois telefones registrados não correspondem e os três telefones NULL não aparecem em nenhum dos resultados.
Um % no início não fornece a um índice comum um texto inicial fixo para restringir a busca, então uma grande parte da tabela pode ser percorrida. Um início fixo como 'Desk%' pode ajudar um índice adequado. Para datas, use intervalos de datas: LIKE funciona nessas datas de texto, mas o PostgreSQL exige conversão antes de aplicar LIKE a uma coluna DATE real.
Principais conclusões
- LIKE compara o valor inteiro;
%abrange qualquer quantidade de caracteres e_exatamente um. - Coloque
%no início, no fim ou em ambos para controlar onde um fragmento pode aparecer. - O tratamento de maiúsculas e minúsculas varia conforme o banco de dados e a colação; LOWER ajuda com esses nomes ASCII.
- ESCAPE permite que um caractere curinga represente seu caractere literal.
- NULL não corresponde nem a LIKE nem a NOT LIKE.
- Caracteres curinga no início podem fazer uma busca percorrer mais dados; use intervalos para datas.
4Considere os valores ausentes
Dados ausentes alteram quais registros um filtro pode encontrar. Uma contagem de estoque igual a zero, uma cadeia de telefone vazia e um valor não registrado informam coisas diferentes, mesmo que uma ferramenta de consulta faça algumas células parecerem iguais. Você usará testes explícitos de valores ausentes e acompanhará o terceiro valor lógico, desconhecido. Essas regras explicam por que um filtro e seu oposto podem excluir as mesmas linhas e como incluí-las quando a pergunta exigir.
4.1 NULL, zero e texto vazio
NULL marca um valor ausente: um valor pode ser desconhecido, não registrado ou não aplicável. Ele é diferente de um zero conhecido ou de um texto conhecido sem caracteres.
Entenda o que significa um valor ausente
Lamp Shade tem stock = 0. Sua quantidade registrada é zero, portanto está sem estoque. Bookshelf tem stock NULL: a quantidade não foi registrada. O banco de dados não pode informar que há zero unidades nem qualquer outra quantidade.
A distinção muda a pergunta que você pode responder:
| Pergunta | Condição | Resultado |
|---|---|---|
| Quais produtos estão sem estoque? | stock = 0 | Lamp Shade |
| Quais quantidades em estoque são desconhecidas? | stock IS NULL | Bookshelf |
| Quais quantidades estão registradas? | stock IS NOT NULL | Os outros sete produtos |
Uma célula que parece vazia em uma ferramenta de consulta não basta para distinguir esses estados. Algumas ferramentas mostram NULL como uma célula vazia; outras exibem NULL. Teste diretamente o valor armazenado.
Use os testes de valores ausentes
SELECT first_name
FROM employees
WHERE phone IS NULL;
Ben, Emma e Hugo não têm telefone registrado. IS NULL resulta em verdadeiro para seus valores ausentes. Para encontrar os cinco funcionários com telefone registrado, use phone IS NOT NULL: Ana, Chloe, David, Farid e Grace.
Não escreva phone = NULL para encontrar telefones ausentes. Uma comparação comum que envolve NULL resulta em desconhecido, mesmo quando ambos os lados são NULL. WHERE mantém apenas as linhas verdadeiras, então = NULL não retorna nenhuma. <> NULL tem o mesmo problema. IS NULL é um teste do marcador de ausência e fornece uma resposta definida, verdadeira ou falsa, para esses valores de uma única coluna.
A forma NOT phone IS NULL também encontra telefones presentes no SQLite e no PostgreSQL, mas phone IS NOT NULL torna o teste pretendido mais fácil de ler.
Separe três tipos de texto
| Expressão SQL | O que representa |
|---|---|
NULL | Um valor ausente |
'' | Um valor de texto conhecido com zero caracteres |
'NULL' | Quatro letras comuns |
SQLite, PostgreSQL, MySQL e SQL Server distinguem texto vazio de NULL. phone = '' encontraria cadeias vazias, não os telefones ausentes de Ben, Emma ou Hugo. Se uma coluna puder conter ambos, use phone IS NULL OR phone = '' para encontrar qualquer um dos estados. O Oracle trata um valor de texto vazio como NULL, então essa distinção muda quando você troca de banco de dados.
Aplique o enunciado e o esquema
“Ausente”, “não registrado” e “não atribuído” indicam IS NULL. department IS NULL encontra Grace. Seu departamento ausente não significa que o texto do departamento seja a palavra 'NULL', nem estabelece a qual departamento ela pertence.
A definição da tabela pode marcar uma coluna como NOT NULL, o que significa que uma linha armazenada não pode ter NULL nessa coluna. Uma consulta IS NULL nessa coluna não retorna linhas. Verifique essa regra ao examinar um esquema: colunas que permitem dados ausentes precisam de atenção especial quando você cria exclusões ou combina condições.
Principais conclusões
- NULL é um marcador de ausência; zero e texto vazio são valores conhecidos.
- IS NULL encontra valores ausentes, e IS NOT NULL encontra valores presentes.
= NULLe<> NULLnão conseguem encontrar linhas por meio de comparações comuns.'NULL'entre aspas é texto, e o Oracle trata texto vazio de forma diferente dos outros bancos de dados apresentados.- Uma coluna NOT NULL não pode armazenar NULL.
4.2 Verdadeiro, falso e desconhecido
Uma condição em SQL pode ser verdadeira, falsa ou desconhecida. Valores ausentes tornam o terceiro estado necessário: sem uma quantidade registrada, um banco de dados não consegue determinar se essa quantidade está acima de um limite.
Uma condição e seu oposto
Para Bookshelf, stock > 10 é desconhecido porque o estoque é NULL. O mesmo vale para stock <= 10. WHERE mantém apenas condições verdadeiras e exclui tanto as falsas quanto as desconhecidas.
Na tabela de produtos, stock > 10 retorna quatro linhas e stock <= 10 retorna três. Juntas, elas abrangem sete dos oito produtos. Bookshelf está ausente de ambas. Aplicar NOT não o recupera: NOT desconhecido é desconhecido, então NOT (stock > 10) ainda seleciona apenas as três quantidades conhecidas de no máximo 10.
Isso difere de um valor que não atende a uma condição. O zero conhecido de Lamp Shade torna stock > 10 falso, então NOT o torna verdadeiro. Uma quantidade ausente não fornece uma comparação definida desse tipo para inverter.
Combine desconhecido com outro teste
| Combinação | Resultado |
|---|---|
| Desconhecido AND falso | Falso |
| Desconhecido AND verdadeiro | Desconhecido |
| Desconhecido AND desconhecido | Desconhecido |
| Desconhecido OR verdadeiro | Verdadeiro |
| Desconhecido OR falso | Desconhecido |
| Desconhecido OR desconhecido | Desconhecido |
Bookshelf custa 120,00. Em stock > 10 OR price > 100, a condição de preço é verdadeira. OR precisa de apenas uma parte verdadeira, então a linha é mantida mesmo que a comparação do estoque seja desconhecida. Em stock > 10 AND price > 100, a condição de estoque continua sem resolução, então o resultado é desconhecido e a linha é excluída.
Inclua valores ausentes deliberadamente
SELECT first_name
FROM employees
WHERE department <> 'Sales'
OR department IS NULL;
Isso retorna Ben, David, Farid, Hugo e Grace. A comparação sozinha retornaria quatro, deixando Grace de fora. O ramo IS NULL inclui explicitamente funcionários cujo departamento não foi atribuído. Se esses funcionários pertencem a “fora de Sales” é uma questão sobre a resposta pretendida; a consulta deve expressar essa escolha.
Um valor NULL em uma lista NOT IN pode bloquear o resultado inteiro. department NOT IN ('Sales', NULL) significa que o departamento deve ser diferente de Sales e diferente de NULL. A última comparação é desconhecida para todas as linhas, então a condição completa nunca é verdadeira. IN ainda mantém correspondências reais: department IN ('Sales', NULL) seleciona os três funcionários de Sales, mas não encontra Grace.
Um valor testado ausente também produz desconhecido para LIKE e para um intervalo BETWEEN comum. IS NULL e IS NOT NULL fornecem respostas definidas para essas colunas escalares. Verifique valores ausentes com esses testes separadamente quando uma contagem de linhas parecer surpreendente.
Saiba quando valores NULL são agrupados
NULL = NULL continua sendo desconhecido; não se sabe se dois números de telefone ausentes são o mesmo número. DISTINCT, porém, trata valores ausentes repetidos como duplicatas, e ORDER BY os coloca juntos. Para uma comparação que trata deliberadamente dois valores NULL como iguais, SQLite e PostgreSQL também oferecem IS NOT DISTINCT FROM.
Principais conclusões
- WHERE mantém linhas verdadeiras e remove linhas falsas e desconhecidas.
- NOT mantém desconhecido sem alteração; filtros negados ainda podem deixar de fora linhas com NULL.
- Um ramo verdadeiro de OR pode manter uma linha com outro ramo desconhecido.
- Adicione IS NULL explicitamente quando valores ausentes devem fazer parte da resposta.
- Um NULL em uma lista NOT IN significa que nenhuma linha pode passar por esse filtro de exclusão.
- A remoção de duplicatas agrupa valores NULL, embora a igualdade comum de NULL seja desconhecida.
5Ordene resultados e escolha uma página
Um limite de linhas só ganha significado depois que você decide quais linhas devem vir primeiro. A ordenação pode organizar números, textos ou datas, e colunas de ordenação posteriores resolvem empates nas anteriores. Valores ausentes e linhas empatadas exigem atenção quando uma lista curta ou uma página precisa ser reproduzível. Você criará ordenações totais, aplicará limites após a filtragem e reconhecerá as diferentes sintaxes de limite de linhas usadas por sistemas de banco de dados comuns.
5.1 Ordem crescente e decrescente
ORDER BY define a ordem das linhas do resultado. Sem ele, a SQL não garante qual linha aparece primeiro, mesmo quando uma tabela pequena parece retornar a mesma ordem todas as vezes.
Escolha a direção
| Direção | Números | Datas completas | Texto |
|---|---|---|---|
ASC | Menor primeiro | Mais antiga primeiro | Ordem da colação |
DESC | Maior primeiro | Mais recente primeiro | Ordem inversa da colação |
ASC é o padrão. ORDER BY salary e ORDER BY salary ASC solicitam a mesma direção. “Maior salário primeiro” exige ORDER BY salary DESC.
SELECT first_name, salary
FROM employees
ORDER BY salary DESC;
Leia o resultado do maior para o menor: Farid 83000, Ben 71000, Emma 65000, David 60000, Hugo 58000, Ana 52000, Chloe 48000 e Grace 45000. O banco de dados reorganiza as linhas do resultado; essa consulta não altera a tabela armazenada.
Filtre antes de ordenar
SELECT name, price
FROM products
WHERE category = 'Lighting'
ORDER BY price;
Apenas as três linhas de Lighting entram nesse resultado. Seus preços em ordem crescente produzem Lamp Shade 15,50, Desk Lamp 24,99 e depois Floor Lamp 89,00. ORDER BY vem depois de WHERE na instrução. Inverter essas cláusulas é um erro de sintaxe.
A coluna de ordenação não precisa ser exibida. SELECT first_name FROM employees ORDER BY salary DESC; fornece a mesma ordem de nomes sem mostrar os salários. O PostgreSQL restringe isso quando DISTINCT está presente: uma consulta DISTINCT deve selecionar suas colunas de ordenação.
Leia o tipo de dados armazenado
Colunas numéricas são ordenadas por magnitude numérica. Colunas de texto são ordenadas por caracteres segundo sua colação. Os valores de texto '10', '9' e '100' são ordenados como '10', '100', '9' segundo a ordenação comum de caracteres. Essa não é uma classificação numérica correta, portanto verifique o tipo da coluna quando os valores parecerem fora de ordem.
Os valores de hire_date do exemplo são datas completas em texto, com largura fixa e ano primeiro. ORDER BY hire_date começa com Farid em 2017-09-12 e termina com Grace em 2024-02-19. DESC inverte essa ordem para apresentar as contratações mais recentes primeiro. Datas de texto com o mês primeiro, como MM/DD/YYYY, são comparadas pelo mês antes do ano e não podem fornecer uma ordem cronológica confiável entre anos.
A ordem do texto depende da colação
A colação binária padrão do SQLite coloca letras ASCII maiúsculas antes das minúsculas. Segundo essa regra, 'Zebra' precede 'apple', e 'é' vem depois de 'z'. Muitos bancos de dados PostgreSQL usam colações que consideram o idioma e produzem outra ordem. O uso consistente de maiúsculas ajuda, mas as regras de comparação do banco de dados ainda determinam a ordem dos caracteres acentuados e de outros caracteres.
Use nomes de colunas para especificar a ordenação com clareza. ORDER BY 2 DESC significa o segundo item da lista SELECT, então mover colunas pode alterar silenciosamente a ordenação. ORDER BY 'salary' indica uma constante de texto, não a coluna de salário: o SQLite não obtém uma ordenação útil com isso, e o PostgreSQL o rejeita. Escreva ORDER BY salary.
Principais conclusões
- ORDER BY determina a ordem das linhas; ASC é o padrão e DESC inverte a direção.
- WHERE filtra linhas antes de elas serem ordenadas.
- A magnitude numérica, a representação das datas e a colação do texto determinam o que significa “crescente”.
- Indique explicitamente as colunas de ordenação para evitar constantes entre aspas e mudanças de posição das colunas.
5.2 Várias colunas de ordenação, empates e valores ausentes
Uma segunda coluna de ordenação só importa quando há empate na primeira. Pense em uma lista ordenada de funcionários: agrupe primeiro por cidade e depois ordene os nomes dentro de cada cidade.
Acompanhe as colunas de ordenação da esquerda para a direita
SELECT last_name, city
FROM employees
ORDER BY city, last_name;
O resultado começa com Kim e Okafor em Boston. Depois vêm Haddad, Lopez, Nguyen e O'Neill em Chicago. Brown e Carter em Denver vêm por último. last_name não compete com city; ele determina a ordem apenas dentro de uma mesma cidade.
Inverter as colunas altera a ordem principal. ORDER BY last_name, city ordena principalmente pelo sobrenome e consulta a cidade apenas quando há empate nos sobrenomes. Use uma cláusula ORDER BY com vírgulas entre suas colunas de ordenação. Uma segunda cláusula ORDER BY é inválida.
Defina a direção de cada coluna
ORDER BY department, salary DESC significa departamento em ordem crescente e depois salário em ordem decrescente dentro de cada departamento. DESC pertence apenas a salary. Para colocar ambos em ordem decrescente, escreva department DESC, salary DESC.
Na ordenação padrão de NULL do SQLite, a primeira forma coloca o departamento ausente de Grace primeiro. IT vem em seguida com Farid e depois Ben; Marketing tem David e depois Hugo; Sales tem Emma, Ana e depois Chloe. Você está lendo uma hierarquia de comparações, não ordenando primeiro todas as linhas por salário e depois ignorando essa ordem.
Resolva um empate com um valor único
Linhas iguais em todas as colunas de ordenação podem aparecer em qualquer ordem. ORDER BY city não determina qual funcionário de Chicago vem primeiro. Uma ordenação total acrescenta uma última coluna que identifica cada linha de forma única:
SELECT first_name, city
FROM employees
ORDER BY city, employee_id;
Os identificadores resolvem todos os empates de cidade. Para dados inalterados, isso faz com que um LIMIT ou uma página posterior selecione uma parte reproduzível da lista ordenada. Um critério de desempate único determina quais linhas aparecem em um ponto de corte; ele não inclui linhas empatadas adicionais.
Posicione valores ausentes deliberadamente
Os padrões dos bancos de dados diferem:
| Banco de dados | NULL em ordem ASC | NULL em ordem DESC |
|---|---|---|
| SQLite, MySQL, SQL Server | Primeiro | Último |
| PostgreSQL, Oracle | Último | Primeiro |
Assim, a consulta de departamento coloca Grace por último no PostgreSQL com seu padrão, embora a coloque primeiro no SQLite. Essa diferença é independente da direção do salário.
SELECT first_name, department, salary
FROM employees
ORDER BY department NULLS LAST, salary DESC;
SQLite 3.30 ou posterior, PostgreSQL e Oracle oferecem suporte a NULLS FIRST e NULLS LAST. Aqui, eles colocam Grace depois de todos os departamentos registrados, mantendo a ordem salarial dentro de cada departamento. MySQL e SQL Server não aceitam essas cláusulas.
Interprete uma hierarquia solicitada na mesma sequência em que é enunciada: “por departamento, com os maiores salários primeiro em cada departamento” fornece department, salary DESC. “Em ordem alfabética por sobrenome e depois por nome” fornece last_name, first_name. Acrescente um identificador por último quando precisar de uma ordem reproduzível entre pessoas com nomes idênticos.
Principais conclusões
- Colunas posteriores de ORDER BY resolvem empates nas anteriores.
- ASC ou DESC se aplica à sua própria coluna; direções omitidas assumem ASC como padrão.
- Adicionar uma coluna de ordenação final única torna a ordem total para dados inalterados.
- A posição de NULL depende do banco de dados; as cláusulas NULLS FIRST/LAST, quando disponíveis, definem-na explicitamente.
- Um critério de desempate determina a escolha das linhas sem ampliar um LIMIT para incluir todos os empates.
5.3 Primeiros resultados e páginas com LIMIT
LIMIT mantém no máximo uma quantidade escolhida de linhas de resultado. Ele não decide quais linhas devem vir primeiro. Use ORDER BY para dar a uma lista curta um significado como maior salário, mais recente ou mais barato.
Ordene e depois corte
SELECT first_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 3;
Os salários ordenados começam com Farid 83000, Ben 71000 e Emma 65000, então essas três linhas permanecem. Sem ORDER BY, LIMIT 3 retorna três linhas quaisquer, sem garantia de que sejam as pessoas com os maiores salários.
WHERE atua antes do limite. WHERE city = 'Boston' ORDER BY salary DESC LIMIT 5 retorna apenas David e Grace porque apenas dois funcionários atendem à condição. LIMIT é um máximo, não uma solicitação para inventar linhas adicionais. LIMIT 0 não retorna nenhuma.
Pule linhas para uma página posterior
OFFSET pula linhas antes de LIMIT contar as linhas a retornar. ORDER BY salary DESC LIMIT 3 OFFSET 3 pula Farid, Ben e Emma e depois retorna David, Hugo e Ana: posições quatro a seis.
Para a página k com n linhas por página, pule (k − 1) × n linhas. A página três com três linhas por página usa LIMIT 3 OFFSET 6. Restam apenas Chloe e Grace. A primeira página tem deslocamento zero, não um.
“Segunda linha” e “segundo valor distinto” são solicitações diferentes. ORDER BY salary DESC LIMIT 1 OFFSET 1 retorna Ben com 71000 aqui. Se dois funcionários compartilhassem o maior salário, essa consulta retornaria outra pessoa com o maior salário. Para encontrar o segundo salário distinto, selecione DISTINCT salary antes de ordenar e pular linhas.
Resolva o ponto de corte
ORDER BY city LIMIT 3 inclui os dois funcionários de Boston e um de Chicago, mas não especifica qual funcionário de Chicago. ORDER BY city, employee_id LIMIT 3 seleciona David, Grace e Ana. O identificador único resolve o ponto de corte.
Para manter todos os empatados no último valor de ordenação, PostgreSQL 13 ou posterior e Oracle oferecem suporte a FETCH FIRST 3 ROWS WITH TIES. Com ORDER BY city, ele mantém seis linhas: as duas de Boston e as quatro de Chicago. Se ORDER BY também incluir um identificador único, as linhas não poderão empatar na chave de ordenação completa.
Reconheça a sintaxe do banco de dados
| Banco de dados | Um limite de três linhas |
|---|---|
| SQLite, PostgreSQL, MySQL | ORDER BY salary DESC LIMIT 3 |
| PostgreSQL, Oracle 12c ou posterior | ORDER BY salary DESC FETCH FIRST 3 ROWS ONLY |
| SQL Server | SELECT TOP (3) first_name, salary FROM employees ORDER BY salary DESC; |
A SQL padrão usa OFFSET e FETCH, não LIMIT. PostgreSQL e Oracle aceitam OFFSET 3 ROWS FETCH FIRST 3 ROWS ONLY. O SQL Server usa ORDER BY salary DESC OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY; ORDER BY é obrigatório para essa forma de paginação.
SQLite e MySQL também aceitam LIMIT 6, 3, com o deslocamento primeiro. Prefira LIMIT 3 OFFSET 6 para que os papéis fiquem explícitos. A paginação executa novamente uma consulta para cada página. Uma ordenação total mantém as páginas consistentes enquanto os dados permanecem inalterados; inserções ou exclusões entre solicitações ainda podem fazer as páginas repetirem ou pularem registros.
Principais conclusões
- ORDER BY determina quais linhas vêm primeiro; LIMIT mantém no máximo a quantidade solicitada.
- OFFSET pula linhas antes de LIMIT contar; a primeira página usa deslocamento zero.
- Selecione DISTINCT primeiro ao classificar valores distintos em vez de linhas individuais.
- Um critério de desempate único determina um ponto de corte; WITH TIES pode incluir linhas adicionais empatadas na chave de ordenação completa.
- LIMIT, TOP e OFFSET/FETCH são formas de limitar linhas específicas de cada banco de dados.
- Dados alterados podem deslocar os limites das páginas entre solicitações.
6Construa e verifique uma consulta completa
Uma pergunta do ambiente de trabalho geralmente combina várias escolhas: quais registros contam, quais detalhes mostrar e quais linhas vêm primeiro. Planejar essas escolhas separadamente ajuda você a escrever uma consulta cujas partes são coerentes entre si. A ordem escrita das cláusulas e a ordem lógica explicam por que um filtro pode usar uma coluna oculta e por que um limite se aplica às linhas que atendem à condição. Você também verificará limites, dados ausentes e empates antes de confiar em um resultado que parece plausível.
6.1 Ordem escrita e processamento lógico
As cláusulas SQL têm uma ordem fixa de escrita. Sua ordem lógica explica o resultado como uma sequência de decisões, mesmo quando o banco de dados usa um plano de execução interno diferente.
Escreva a instrução na ordem das cláusulas
SELECT DISTINCT city
FROM employees
WHERE department = 'Sales'
ORDER BY city
LIMIT 2 OFFSET 0;
SELECT e FROM identificam as colunas solicitadas e a tabela de origem. As outras cláusulas são opcionais, mas, quando presentes, mantêm esta ordem: WHERE, ORDER BY, LIMIT e depois OFFSET nessa forma com LIMIT. DISTINCT fica imediatamente após SELECT.
Use uma cláusula WHERE com várias condições unidas. Um segundo WHERE é um erro de sintaxe. O mesmo vale para ORDER BY: coloque várias colunas de ordenação em uma cláusula, separadas por vírgulas. Mover WHERE para depois de ORDER BY não solicita uma ordem de processamento diferente; produz SQL inválida.
Acompanhe as decisões lógicas
| Etapa lógica | O que acontece no exemplo |
|---|---|
| FROM | Lê as linhas de funcionários. |
| WHERE | Mantém Ana, Chloe e Emma em Sales. |
| SELECT | Mantém seus valores de cidade: Chicago, Chicago, Denver. |
| DISTINCT | Reduz esses valores a Chicago e Denver. |
| ORDER BY | Coloca Chicago antes de Denver. |
| OFFSET e LIMIT | Não pula nenhuma linha e retorna no máximo duas. |
O resultado é Chicago, depois Denver. A cidade repetida desaparece antes de o limite contar as linhas de resultado. Você não está selecionando dois funcionários para depois perguntar se moram em cidades diferentes.
O otimizador pode usar um plano de execução física diferente que produza o mesmo resultado dessa sequência lógica.
Use colunas onde estão disponíveis
WHERE testa as linhas de origem antes de SELECT escolher as colunas exibidas:
SELECT first_name
FROM employees
WHERE salary > 60000;
Isso funciona sem salary na saída. Os nomes que atendem à condição são Ben, Emma e Farid. Salary ainda é uma coluna de cada linha de origem quando o teste é feito.
Da mesma forma, filtrar antes de limitar é essencial para obter o primeiro resultado dentro de um grupo:
SELECT first_name
FROM employees
WHERE department = 'Sales'
ORDER BY salary DESC
LIMIT 1;
A resposta é Emma. Os funcionários de Sales são selecionados primeiro; seus salários são então classificados. Selecionar primeiro a pessoa com o maior salário da empresa e testar essa única linha para Sales deixaria de fora a resposta pretendida, pois Farid pertence a IT.
Torne a estrutura visível
Escreva uma cláusula por linha e coloque condições mais longas em linhas separadas e recuadas. Para “produtos de Furniture abaixo de 200 dólares, com o maior preço primeiro”, use:
SELECT name, price
FROM products
WHERE category = 'Furniture'
AND price < 200
ORDER BY price DESC;
Office Chair, com preço de 149,00, vem antes de Bookshelf, com 120,00. As duas condições compartilham um WHERE, o limite numérico não tem símbolo de moeda e ORDER BY ordena as linhas que passaram. Verificar cada linha de acordo com sua função facilita a localização de erros de sintaxe e de interpretações incorretas.
Principais conclusões
- Escreva SELECT, FROM, WHERE, ORDER BY e LIMIT na ordem exigida para as cláusulas.
- Na ordem lógica, leia a tabela, filtre, selecione colunas, remova duplicatas, ordene e depois recorte as linhas.
- WHERE pode testar colunas de origem que SELECT não exibe.
- Filtrar antes de classificar encontra o primeiro resultado dentro do grupo solicitado.
6.2 De uma solicitação a uma resposta verificada
Antes de escrever SQL, identifique as decisões separadas que estão implícitas em uma solicitação cotidiana. Cada decisão pertence a uma cláusula, e cada cláusula pode ser verificada em relação à resposta pretendida.
Tome seis decisões
- Qual tabela contém os registros? Escolha FROM.
- Quais registros atendem à condição? Construa WHERE.
- Quais campos respondem à pergunta? Escolha SELECT.
- Valores repetidos no resultado são úteis? Decida sobre DISTINCT.
- O que deve vir primeiro? Construa ORDER BY.
- Há um máximo ou uma página? Adicione LIMIT e OFFSET.
Para “pelo menos”, inclua a igualdade. “Um de” sugere IN, “contém” sugere um padrão LIKE com sinais de porcentagem nas duas extremidades, “ausente” sugere IS NULL e “valores distintos” sugere DISTINCT. Uma solicitação dos primeiros n resultados precisa de uma direção de ordenação e de um limite.
Crie uma lista curta de funcionários
“Mostre os nomes e as datas de contratação dos três funcionários contratados mais recentemente fora de Sales que têm telefone registrado, começando pelo mais recente.” Inclua funcionários sem departamento atribuído no significado de fora de Sales dessa solicitação.
Comece com employees. A regra de departamento para selecionar as linhas é department <> 'Sales' OR department IS NULL. Agrupe essa escolha para que a regra de telefone se aplique a ambos os ramos. Mostre nomes e datas e depois classifique as linhas que atendem às condições:
SELECT first_name, last_name, hire_date
FROM employees
WHERE (department <> 'Sales' OR department IS NULL)
AND phone IS NOT NULL
ORDER BY hire_date DESC
LIMIT 3;
Grace Okafor em 2024-02-19 é a primeira, David Kim em 2020-11-23 é o segundo e Farid Haddad em 2017-09-12 é o terceiro. Remover o ramo IS NULL exclui Grace e deixa apenas dois resultados. Para uma solicitação pouco clara, decida como os departamentos ausentes devem contar e informe a escolha junto com a resposta.
Combine categoria, preço e estoque
“Quais produtos de Lighting ou Storage custam menos de 20 dólares e estão em estoque, começando pelos mais baratos?” Use IN para as duas opções de categoria e exija uma quantidade positiva conhecida:
SELECT name, price
FROM products
WHERE category IN ('Lighting', 'Storage')
AND price < 20
AND stock > 0
ORDER BY price;
Paper Tray, a 9,99, vem antes de Desk Organizer, a 18,75. Lamp Shade é barato o suficiente e pertence a uma categoria escolhida, mas seu estoque é zero, então não passa no último teste. Uma quantidade ausente de estoque também não passaria, pois não permite determinar que o estoque é positivo.
Verifique as linhas que podem revelar um erro
Comece com SELECT * FROM products LIMIT 5; ao explorar o esquema e alguns registros. Adicione filtros um por vez, verificando mudanças na contagem de resultados e exibindo temporariamente as colunas testadas quando for útil.
Teste limites exatos, valores ausentes, uso de maiúsculas e minúsculas no texto e empates no limite. NOT mostra linhas em que uma condição era falsa; ele não revela linhas em que a condição era desconhecida. Execute testes IS NULL separadamente. Verifique se a saída tem as colunas solicitadas e se ORDER BY resolve todos os empates que afetam a resposta.
Ao transferir a consulta para outro banco de dados, verifique a sintaxe de limite de linhas, as regras de maiúsculas e minúsculas para igualdade e LIKE, as aspas em identificadores, o tratamento de datas e a posição de NULL. Os exemplos usam LIMIT no SQLite e no PostgreSQL; a forma da SQL padrão para limite de linhas é OFFSET com FETCH FIRST.
Principais conclusões
- Planeje separadamente a tabela, as linhas que atendem às condições, as colunas de saída, as duplicatas, a ordenação e a quantidade de linhas.
- Escreva explicitamente a escolha sobre valores ausentes quando uma exclusão deve incluir registros sem atribuição.
- Verifique os limites e os efeitos de cada filtro em relação à pergunta.
- Examine valores NULL separadamente, pois NOT não transforma desconhecido em verdadeiro.
- Verifique novamente maiúsculas e minúsculas, datas, nomes, ordenação de NULL e limites de linhas ao mudar de banco de dados.
Exercícios resolvidos de Consultas com SELECT
1De registros de funcionários a uma lista de cidades
11 passos
- 1IntroduçãoUma tabela, dois tipos de resposta
Uma lista de funcionários e uma lista das cidades dos funcionários usam os mesmos registros, mas precisam de resultados com estruturas diferentes. Um SELECT básico escolhe os campos a exibir. DISTINCT pode então reduzir valores selecionados repetidos. Primeiro construiremos um resultado de funcionários com duas colunas, depois mudaremos a pergunta para cidades distintas e acompanharemos o que desaparece.
- 2ExplicaçãoEscolha as colunas exibidas
Comece com uma solicitação específica: mostre a cidade de cada funcionário seguida de seu nome. Escreva:
SELECT city, first_name FROM employees;A lista SELECT define a ordem das colunas de saída, então a cidade vem primeiro. FROM fornece a tabela. Não há filtro, então todos os oito funcionários contribuem com uma linha; essa consulta simples mantém os registros armazenados inalterados.
- 3ExemploLeia a estrutura do resultado
O registro de Ana contribui com Chicago e Ana; o de Ben contribui com Denver e Ben. Cada funcionário restante contribui com os mesmos dois campos. O resultado, portanto, tem oito linhas e duas colunas. Cidades repetidas permanecem porque essas linhas ainda descrevem pessoas diferentes. Não há ORDER BY, então esses exemplos identificam as linhas sem garantir sua ordem de exibição.
- 4DesafioVerifique uma lista SELECT alterada
O que muda se a consulta se tornar
SELECT first_name FROM employees;? Informe a quantidade de linhas e de colunas.---reveal---
Ela ainda retorna oito linhas, agora com uma coluna, first_name. Remover city de SELECT remove um campo exibido, não registros de funcionários. Seria necessário um filtro ou limite de linhas para reduzir as linhas.
- 5DicaLocalize os erros de sintaxe
Separe os nomes das colunas com vírgulas, mas não coloque vírgula depois do último antes de FROM. Use ponto e vírgula para encerrar a instrução;
--inicia um comentário que vai até o fim da linha. Se o banco de dados informar uma coluna desconhecida, compare a grafia com o esquema.SELECT *é útil para uma primeira análise, enquanto nomes explícitos mantêm um resultado salvo focado. - 6ExplicaçãoPeça cidades distintas
Agora pergunte quais cidades têm funcionários. Os nomes não pertencem mais a essa resposta:
SELECT DISTINCT city FROM employees;As oito entradas de cidade são reduzidas a Chicago, Denver e Boston, sem ordem garantida. DISTINCT remove repetições do resultado selecionado, não da tabela de funcionários armazenada. Cada cidade aparece uma vez, mesmo que várias pessoas morem nela.
- 7ExemploCompare linhas selecionadas completas
Adicione departamento à lista SELECT. Ana e Chloe contribuem com o par Sales-Chicago, que é reduzido a uma linha. Emma contribui com Sales-Denver, que permanece porque a cidade é diferente. O resultado completo de
SELECT DISTINCT department, city FROM employees;tem sete linhas. DISTINCT é escrito uma vez após SELECT e compara todos os campos selecionados em conjunto. - 8DesafioUm identificador único altera a remoção de duplicatas
Quantas linhas
SELECT DISTINCT employee_id, city FROM employees;retornaria e por quê?---reveal---
Todas as oito linhas permanecem. Cada employee_id é único, então cada par de identificador e cidade difere de todos os outros. Cidades repetidas, por si só, não bastam para tornar duplicadas as linhas selecionadas completas.
- 9Ideia-chaveDecida o que uma linha NULL informa
Uma lista DISTINCT de departamentos contém Sales, IT, Marketing e uma linha NULL para Grace. Marcadores de ausência repetidos também seriam reduzidos a um só. Essa linha informa que um departamento não está registrado; ela não é outro departamento nomeado. O agrupamento de duplicatas reúne valores NULL, embora uma comparação comum
NULL = NULLseja desconhecida. - 10DesafioTermine com uma lista curta ordenada
Preveja
SELECT DISTINCT city FROM employees ORDER BY city LIMIT 2;. Informe os valores na ordem em que são retornados e explique o que o limite conta.---reveal---
Boston, depois Chicago. DISTINCT primeiro reduz os valores de cidade a três; ORDER BY ordena esses valores e LIMIT mantém dois. Ele conta cidades distintas no resultado após a remoção de duplicatas, não dois registros de funcionários.
- 11RecapitulaçãoAjuste a saída à pergunta
Um resultado de funcionários mantém campos de identificação; uma lista de cidades seleciona apenas a cidade com DISTINCT. As colunas selecionadas determinam as comparações de duplicatas, enquanto ORDER BY determina a ordem das linhas. Ao alterar uma consulta, verifique tanto os campos de saída quanto o que uma linha de resultado representa.
2Construa um filtro que expresse sua intenção
13 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoTodo filtro faz uma pergunta precisa
- 2ExplicaçãoInterprete o limite salarial
- 3DesafioInclua o limite quando necessário
- 4DicaEscreva literais numéricos sem adornos
- 5ExplicaçãoColoque um valor de texto entre aspas
- 6ExemploMantenha um apóstrofo dentro do valor
- 7ExplicaçãoUse um limite de data completo
- 8DesafioVerifique uma data com hora
- 9ExplicaçãoUna as condições
- 10ExemploAplique uma regra de cidade às alternativas
- 11DesafioInverta o grupo
- 12DesafioCombine uma data e um grupo de departamentos
- 13RecapitulaçãoAcompanhe uma linha reveladora
3Escolha uma lista exata, um intervalo ou um padrão
15 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoTrês significados de correspondência
- 2ExplicaçãoComece com opções de categoria completas
- 3ExemploAplique uma regra de estoque à lista
- 4DesafioPreveja uma exclusão
- 5ExplicaçãoColoque um preço dentro de um intervalo
- 6DesafioExclua os extremos deliberadamente
- 7DicaCubra um mês inteiro com horas
- 8ExplicaçãoDecida onde o fragmento deve aparecer
- 9ExemploConte um caractere com um sublinhado
- 10ExemploTorne o caractere curinga literal
- 11DesafioVerifique um padrão em suas extremidades
- 12ConexãoVerifique o tratamento de maiúsculas e minúsculas no banco de dados
- 13DesafioConsidere um telefone ausente
- 14DesafioCombine os três tipos de correspondência
- 15RecapitulaçãoEscolha a forma pelo significado
4Encontre dados ausentes e raciocine sobre eles
10 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoUma quantidade não registrada fica sem resolução
- 2ExemploSepare zero de ausência
- 3ExplicaçãoTeste a presença diretamente
- 4DesafioVerifique texto vazio
- 5ExplicaçãoAcompanhe uma comparação e seu oposto
- 6ExemploDeixe um ramo OR verdadeiro decidir
- 7DesafioUm ramo AND falso pode decidir o resultado
- 8Ideia-chaveEvite NULL dentro de uma lista de exclusão
- 9DesafioInclua departamentos ausentes e exija telefones
- 10RecapitulaçãoExamine dados ausentes separadamente
5Construa uma página ordenada e reproduzível
15 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoUma página é um recorte de uma resposta ordenada
- 2ExemploEscolha o maior primeiro
- 3DesafioOrdene apenas os produtos que atendem à condição
- 4DicaSaiba se a ordenação é numérica
- 5ExplicaçãoLeia as prioridades de ordenação a partir da esquerda
- 6DesafioDefina a direção de cada coluna de ordenação
- 7ExplicaçãoResolva os empates restantes
- 8ConexãoPosicione valores ausentes explicitamente
- 9ExemploMantenha as três primeiras linhas classificadas
- 10ExemploPasse da primeira página
- 11Ideia-chaveA posição de uma linha difere da posição de um valor distinto
- 12DesafioExamine um ponto de corte com empate
- 13DicaReconheça outra forma de limitar linhas
- 14DesafioMantenha a segunda página de cidades
- 15RecapitulaçãoDefina a classificação antes do recorte
6Transforme e verifique uma solicitação de trabalho
12 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoSepare as decisões de uma solicitação
- 2ExplicaçãoEscreva as cláusulas em uma ordem válida
- 3ExemploAcompanhe o modelo lógico
- 4DesafioFiltre antes de escolher o primeiro colocado
- 5ExplicaçãoIdentifique a solicitação sobre funcionários
- 6ExemploTorne explícita a regra de departamento
- 7ExemploAplique a exigência de telefone
- 8ExemploClassifique os registros que atendem às condições
- 9DesafioVerifique a decisão sobre valores ausentes
- 10DesafioConecte as cláusulas em uma sequência
- 11DicaEscolha verificações que revelem erros
- 12RecapitulaçãoConfira a resposta em relação à solicitação
Questões de Consultas com SELECT
Conjunto 1: Listas, intervalos e padrões de caracteres10 Questões de Prática
Questão 1 de 10
fee tem os valores 12, 18, 24 e 30. Quais valores passam em WHERE fee BETWEEN 18 AND 30?Mostrar respostaOcultar resposta
Questão 2 de 10
report?Mostrar respostaOcultar resposta
Questão 3 de 10
requests tem as linhas (request_id, region) (31, 'South'), (32, 'East'), (33, 'South'). Qual conjunto de identificadores passa em WHERE region IN ('South', 'South')?Mostrar respostaOcultar resposta
Questão 4 de 10
labels, qual conjunto de valores corresponde a label LIKE '__7%': 'AB7', 'A7', 'AB70' e 'ABC7'?Mostrar respostaOcultar resposta
Questão 5 de 10
temperature contém 4, 9, 14, 19 e NULL. Quais valores passam em WHERE temperature NOT BETWEEN 9 AND 14?Mostrar respostaOcultar resposta
Questão 6 de 10
promo_code contém 'VIP_2', 'VIPA2', 'VIP_' e 'VIP2'. Qual conjunto corresponde a WHERE promo_code LIKE 'VIP!_%' ESCAPE '!'?Mostrar respostaOcultar resposta
Questão 7 de 10
appointments armazena texto com hora no formato de largura fixa YYYY-MM-DD HH:MM:SS. Qual condição seleciona todos os compromissos de fevereiro de 2028?Mostrar respostaOcultar resposta
Questão 8 de 10
word LIKE 'map%' entre 'Maple', 'map', 'roadmap' e 'MAPS'?Mostrar respostaOcultar resposta
Questão 9 de 10
members tem as linhas (member_id, tier) (41, 'Gold'), (42, 'Silver'), (43, NULL). Qual conjunto de identificadores passa em WHERE tier IN ('Silver', NULL)?Mostrar respostaOcultar resposta
Questão 10 de 10
shipments registra um port por linha. Qual condição exclui tanto Oakland quanto Tacoma quando todos os valores de port estão registrados?Mostrar respostaOcultar resposta
Conjunto 2: Valores ausentes e filtros combinados10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
jobs contém as linhas (job_id, hours, urgent) (51, NULL, 'yes'), (52, 6, 'no'), (53, 2, 'yes'), (54, NULL, 'no'). Qual conjunto passa em WHERE NOT (hours > 4) OR urgent = 'yes'?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
files tem os valores de folder 'Archive', 'Active' e NULL. Qual condição inclui Active e a pasta ausente, excluindo Archive?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
routes tem as linhas (route_id, depot) (61, 'A'), (62, 'B'), (63, NULL). Qual conjunto de identificadores passa em WHERE depot NOT IN ('A', NULL) OR depot IS NULL?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
contacts do SQLite armazena os valores de phone NULL, '', 'NULL' e '555-0188'. Quantas linhas passam em WHERE phone IS NULL?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
devices tem battery_pct = NULL e status = 'ready'. O que acontece com WHERE battery_pct > 50 OR status = 'ready'?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
email registrado, incluindo texto vazio se ele estiver armazenado como valor no PostgreSQL?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
load: 0, 3, 7, NULL, NULL. Duas consultas usam WHERE load > 3 e WHERE NOT (load > 3). Quais são suas quantidades de linhas, nessa ordem?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
deliveries tem os valores de district 'Hill', NULL, 'Hill', NULL e 'Lake'. Quantas linhas SELECT DISTINCT district FROM deliveries; retorna?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
WHERE rating >= 4 e depois verifica as linhas excluídas com WHERE NOT (rating >= 4). Alguns registros não aparecem em nenhum dos resultados. Qual teste adicional revela registros cuja avaliação não foi registrada?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
messages tem os assuntos 'Note A', 'Alert', NULL e 'Note B'. Quantas linhas passam em WHERE subject NOT LIKE 'Note%'?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 3: Colunas, comparações e condições claras10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
parcels armazena weight_kg numérico. Qual condição mantém encomendas que pesam no máximo 8 quilogramas?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
D'Arcy em uma coluna surname?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
tickets tem status e priority numérica. Qual condição seleciona chamados abertos ou pendentes, cada um com prioridade de pelo menos 4?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
visits contém os pares (site, day) ('East', 'Mon'), ('East', 'Mon'), ('East', 'Tue') e ('West', 'Mon'). Quantas linhas SELECT DISTINCT site, day FROM visits; retorna?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
team = 'Blue', city = 'Austin' e score = 62. Ela passa em WHERE team = 'Blue' OR city = 'Miami' AND score >= 80? Por quê?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
rooms tem 12 linhas. Qual é a estrutura do resultado de SELECT floor, room_name FROM rooms;?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
YYYY-MM-DD. Qual condição seleciona datas após o ano-calendário de 2025?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
zone é North ou West?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
loans tem os valores numéricos de days_late 0, 2, 5 e NULL. Quantas linhas passam em WHERE days_late <> 0?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
stockrooms tem as linhas (room_id, building) (1, 'C'), (2, 'A'), (3, 'A'), (4, 'B'), (5, 'C'). Quais valores ordenados resultam de SELECT DISTINCT building FROM stockrooms ORDER BY building DESC LIMIT 2;?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 4: Classificação, empates e páginas posteriores10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
duration_minutes tem os valores 16, 4 e 23. Qual é sua ordem em ORDER BY duration_minutes?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
racers tem as linhas (racer_id, group_name, points) (71, 'A', 8), (72, 'B', 12), (73, 'A', 15). Qual ordem de identificadores resulta de ORDER BY group_name, points DESC?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
orders tem valores únicos de order_id, e várias linhas compartilham tanto order_date quanto total. Qual ORDER BY coloca as datas mais recentes primeiro, os maiores totais dentro de cada data e fornece uma ordenação total?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
offers tem as linhas (offer_id, rate) (81, 40), (82, 40), (83, 35), (84, 30). Qual taxa resulta de SELECT DISTINCT rate FROM offers ORDER BY rate DESC LIMIT 1 OFFSET 1;?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
queues contém os nomes 'Delta', NULL e 'Alpha'. No ORDER BY queue_name ASC padrão, onde fica a linha NULL no SQLite e no PostgreSQL?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
sales tem as linhas (sale_id, amount) (91, 70), (92, 70), (93, 55), (94, 55), (95, 20). No PostgreSQL, quantas linhas SELECT sale_id, amount FROM sales ORDER BY amount DESC FETCH FIRST 3 ROWS WITH TIES; retorna?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
'6', '12' e '100' com colação binária. Qual é sua ordem crescente?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
ORDER BY item_id LIMIT 4 OFFSET 4 em linhas inalteradas com identificadores únicos de 1 a 12. Antes da consulta da página seguinte, a linha 2 é excluída. Quais identificadores LIMIT 4 OFFSET 8 retorna agora com a mesma ordenação?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
tasks tem as linhas (task_id, owner, hours) (101, 'Lee', 9), (102, 'Ari', 8), (103, 'Lee', 5), (104, 'Lee', 3). Qual identificador resulta de SELECT task_id FROM tasks WHERE owner = 'Lee' ORDER BY hours DESC LIMIT 1 OFFSET 1;?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 5: Consultas completas e verificações de resultado10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
courses tem title, fee numérica e places_left numérica. Qual consulta mostra os títulos e preços de cursos abaixo de 75 dólares com vagas disponíveis, começando pelos mais baratos?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
cases tem as linhas (case_id, team, opened_on, phone) (111, 'Red', '2026-06-12', 'x'), (112, NULL, '2026-06-20', 'y'), (113, 'Blue', '2026-06-18', NULL), (114, 'Blue', '2026-06-10', 'z'). Quais identificadores ordenados correspondem aos dois casos mais recentes fora de Red, incluindo equipes não atribuídas, com telefone registrado?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
rentals tem branch = 'East' e returned = 'yes'. Uma consulta deve mostrar locações não devolvidas de East ou West, mas essa linha aparece. O filtro é branch = 'East' OR branch = 'West' AND returned = 'no'. Qual correção aplica a regra de devolução às duas unidades?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
catalog tem nomes de produtos em ASCII. Qual condição encontra nomes que contêm steel sem diferenciar maiúsculas de minúsculas em ASCII tanto no SQLite quanto no PostgreSQL?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
'G', 'G1', 'H2', 'J' e 'J1' com colação binária. Qual conjunto passa em WHERE code BETWEEN 'G' AND 'J' AND code NOT LIKE 'H%'?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
logs contém as linhas (region, channel) ('East', 'web'), ('East', 'web'), ('East', 'store'), ('West', 'web'), ('West', 'store'). Quais linhas ordenadas resultam de SELECT DISTINCT region, channel FROM logs WHERE channel = 'web' ORDER BY region DESC LIMIT 1;?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
bids tem as linhas (bid_id, amount) (121, 90), (122, 90), (123, 80), (124, 80). Quantas linhas SELECT bid_id, amount FROM bids ORDER BY amount DESC, bid_id FETCH FIRST 3 ROWS WITH TIES; retorna?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
sensors contém as linhas (sensor_id, reading, enabled) (131, NULL, 'yes'), (132, 8, 'yes'), (133, 2, 'no'), (134, NULL, 'no'). Qual conjunto passa em WHERE NOT (reading > 5 AND enabled = 'yes')?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
fee > 50, e os únicos registros de teste disponíveis têm taxas 20 e 80. Qual taxa de teste adicional revela o erro mais diretamente?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Travou em uma questão sua? Ajuda com Tarefas
Termos-Chave
A
AND
ASC
price ASC coloca o produto de iluminação mais barato primeiro e o mais caro por último.B
BETWEEN
price BETWEEN 15.50 AND 89.00 inclui produtos com preço exatamente de 15,50 ou 89,00, os dois extremos indicados.C
Caractere curinga de porcentagem (%)
'Lamp%' permite qualquer sufixo após Lamp, inclusive nenhum sufixo para o valor Lamp.Caractere curinga de sublinhado
Cláusula ESCAPE
LIKE 'SPRING!_%' ESCAPE '!' torna o sublinhado após SPRING um caractere literal.Cláusula FROM
SELECT name, price FROM products; identifica products como a origem dos dois campos.Cláusula SELECT
SELECT city, first_name FROM employees; coloca a cidade antes do nome do funcionário.Cláusula WHERE
WHERE salary < 50000 mantém os funcionários que ganham menos de 50000, mesmo quando a saída oculta seus salários.Colação
'Chicago' de 'chicago', então um filtro por 'chicago' não encontra linhas armazenadas como Chicago.Coluna de ordenação
Coluna principal de ordenação
ORDER BY city, last_name, mantendo os nomes de Boston antes dos de Chicago.Combinação de valores selecionados
Comentário SQL
-- pode explicar por que um filtro inclui funcionários sem departamento atribuído sem alterar suas condições.Conjunto de resultados
SELECT city FROM employees; tem oito linhas, permitindo valores de cidade repetidos.Construção incremental de consultas
Consulta
SELECT first_name FROM employees; solicita ao banco de dados o campo de nome de cada funcionário.Critério de desempate
D
DESC
ORDER BY hire_date DESC coloca um funcionário contratado em 2024 antes de um contratado em 2023 na lista de funcionários.Dialeto SQL
DISTINCT
SELECT DISTINCT city FROM employees; lista apenas essas três cidades.E
Extremo do intervalo
BETWEEN 15.50 AND 89.00 está incluído, então produtos com preço exatamente de 15,50 ou 89,00 atendem à condição.F
Formato de data ISO
hire_date >= '2023-01-01' inclui funcionários contratados nessa data ou depois dela em comparações de ordem cronológica.I
Identificador
hire_date nomeia uma coluna, enquanto o texto entre aspas '2024-02-19' representa um valor.ILIKE
name ILIKE '%desk%' pode corresponder a nomes de produtos que contêm o texto Desk com inicial maiúscula.IN
department IN ('IT', 'Marketing') seleciona todos os funcionários de IT ou Marketing sem repetir uma comparação de departamento.Intervalo de datas fechado à esquerda e aberto à direita
'2024-04-01', preservando os horários tardios do último dia.IS NOT DISTINCT FROM
IS NOT NULL
phone IS NOT NULL mantém um funcionário cujo telefone está registrado, mesmo quando o departamento desse funcionário está ausente.IS NULL
phone IS NULL encontra os funcionários cujos registros de funcionários não têm valor de telefone registrado.L
LIKE
name LIKE '%Lamp%' encontra todos os nomes de produtos que contêm Lamp, quer Lamp apareça no início, no meio ou no fim.LIMIT
Limite inclusivo
salary >= 60000.Limite inferior
price BETWEEN 89.00 AND 15.50 excede o limite superior, não deixando correspondências.Linha duplicada no resultado
Lista de valores de IN
(6, 2, 2, 4) corresponde aos mesmos registros de funcionários que (2, 4, 6), apesar de sua ordem e repetição.Literal de texto
'O''Neill' corresponde ao sobrenome O’Neill porque sua aspa duplicada representa um apóstrofo.Literal numérico
20.50 em price < 20.50 não tem aspas, separador de milhares ou símbolo de moeda.Lógica de três valores
price > 100 é verdadeiro.N
NOT
stock > 10 não inclui um produto com estoque ausente, porque essa linha ainda resulta em uma condição desconhecida.NOT BETWEEN
stock NOT BETWEEN 5 AND 40 mantém um produto com estoque zero e outro com sessenta, mas exclui estoque ausente.NOT IN
city NOT IN ('Chicago', 'Denver') mantém os funcionários de Boston porque suas cidades diferem de ambas as entradas.NULL
NULLS LAST
department NULLS LAST coloca funcionários sem departamento registrado depois dos departamentos registrados em consultas nas versões atuais do SQLite e do PostgreSQL.O
OFFSET
Operador de comparação
>= inclui um funcionário com salário de exatamente 60000 em salary >= 60000 porque esse salário é igual ao limite.OR
Ordem das cláusulas
Ordem lógica de processamento
Ordenação total
ORDER BY city, employee_id determina a posição de cada funcionário por meio do identificador único.ORDER BY
ORDER BY salary DESC coloca o funcionário mais bem pago em primeiro no resultado salarial sem alterar nenhum registro de funcionário armazenado.Otimizador de consultas
P
Página
Precedência de operadores
T
Texto vazio
phone = '' verifica texto vazio e não encontra valores de telefone de funcionários que estão ausentes.Tipo DATE
DATE '2022-01-01'; o SQLite não usa essa sintaxe de literal tipado.TOP
SELECT TOP (3) pode substituir LIMIT em uma lista curta de três linhas quando a consulta é escrita para o SQL Server.V
Valor lógico desconhecido
stock > 10, então essa linha não passa no filtro.Verificação do resultado
Verificação dos limites
W
WITH TIES
Sobre esta aula
Crie seus próprios Materiais de Estudo
Transforme suas anotações, slides e documentos em Guias de Estudo, Questões de Prática, Flashcards e mais 6 ferramentas.