Diferenças entre COUNT(*), DISTINCT, UNION e paginação em SQL

Compreendendo as diferenças entre COUNT(*) e COUNT(coluna)

/*
COUNT(coluna_específica): conta o total de elementos não nulos nessa coluna.
COUNT(*): conta o número total de linhas na tabela.
    Uma vez que em cada registro é impossível que todas as colunas sejam NULL,
    se uma linha contiver pelo menos um valor não nulo, ela é considerada válida.
*/

Utilização da cláusula DISTNICT

-- A cláusula DISTINCT deve aparecer imediatamente após SELECT

SELECT DISTINCT departamento FROM funcionarios;

-- Escrita incorreta: DISTINCT deve estar antes de todas as colunas listadas
SELECT nome, DISTINCT cargo FROM funcionarios;  -- ERRO

-- Usado com múltiplas colunas, aplica a desduplicação à combinação dos campos
SELECT DISTINCT cargo, departamento FROM funcionarios;

-- Contando valores únicos em uma coluna
SELECT COUNT(DISTINCT cargo) FROM funcionarios;

Conusltas aninhadas (Subconsultas)

/*
Uma subconsulta é uma instrução SELECT dentro de outra instrução SELECT.
Pode aparecer em diferentes cláusulas:
SELECT ...(subconsulta)...
FROM ...(subconsulta)...
WHERE ...(subconsulta)...
Observação: Uma subconsulta na lista SELECT deve retornar exatamente um valor.
*/

-- Exemplo: Encontrar funcionários com salário acima do mínimo da empresa
SELECT *
FROM empregados
WHERE salario > (SELECT MIN(salario) FROM empregados);

Combinando resultados com UNION

/*
O UNION é frequentemente mais eficiente que um JOIN para simplesmente
concatenar conjuntos de resultados, pois evita o produto cartesiano.

Restrições importantes:
1. Ambas as consultas devem ter o mesmo número de colunas.
   Os tipos de dados devem ser compatíveis (obrigatório no Oracle).
2. A ordenação final deve ser feita com um único ORDER BY no final.
3. UNION (sem ALL) elimina linhas duplicadas e aplica ordenação padrão.
   UNION ALL mantém todas as linhas, sendo mais rápido.
*/

-- Exemplo: Listar funcionários de dois cargos específicos
SELECT nome, cargo FROM empregados WHERE cargo = 'Gerente'
UNION
SELECT nome, cargo FROM empregados WHERE cargo = 'Vendedor';

INETRSECT e MINUS

/*
INTERSECT: retorna apenas as linhas comuns aos dois conjuntos, sem duplicatas.
MINUS: retorna as linhas do primeiro conjunto que não existem no segundo.
Ambas as operações removem duplicatas internamente.
*/

Cláusula LIMIT para paginação

/*
Sintaxe completa: LIMIT [deslocamento], [quantidade]
- deslocamento: índice inicial (começando em 0)
- quantidade: número de registros a retornar

Sintaxe abreviada: LIMIT 5  -- retorna as primeiras 5 linhas

Exemplos de aplicação:
*/

-- Os 5 empregados com maiores salários
SELECT * FROM empregados ORDER BY salario DESC LIMIT 5;

-- Equivalente a:
SELECT * FROM empregados ORDER BY salario DESC LIMIT 0,5;

-- Ranking de salários do 3º ao 5º lugar
SELECT * FROM empregados ORDER BY salario DESC LIMIT 2,3;

-- Ranking de salários do 5º ao 9º lugar
SELECT nome, salario FROM empregados ORDER BY salario DESC LIMIT 4,5;

Fórmula de Paginação Universal

/*
Fórmula: LIMIT (paginaAtual - 1) * registrosPorPagina, registrosPorPagina

Exemplo com 3 registros por página:
    Página 1: LIMIT 0,3   (registros 0,1,2)
    Página 2: LIMIT 3,3   (registros 3,4,5)
    Página 3: LIMIT 6,3   (registros 6,7,8)

Implementação em aplicação:
*/

// Simulação de parâmetros de paginação
int paginaSolicitada = 5;
int itensPorPagina = 10;
int offset = (paginaSolicitada - 1) * itensPorPagina;

// Montagem da consulta
String consultaPaginada = String.format(
    "SELECT * FROM tabela LIMIT %d, %d", offset, itensPorPagina
);

Tags: SQL MySQL Oracle paginação DISTINCT

Publicado em 6-18 18:34