GROUP BY, HAVING, ROLLUP/CUBE/GROUPING SETS
Oracle
-- Basic grouping + HAVING
SELECT city, COUNT(*) AS n
FROM customer
GROUP BY city
HAVING COUNT(*) > 5;
-- Subtotals and grand total with ROLLUP
SELECT city, district, SUM(balance)
FROM customer
GROUP BY ROLLUP(city, district);GROUP BY agrupa as linhas pelas colunas informadas e aplica funções de agregação; HAVING filtra o resultado agrupado (WHERE filtra as linhas antes do agrupamento). ROLLUP gera subtotais hierárquicos + um total geral, CUBE todas as combinações, e GROUPING SETS os agrupamentos selecionados. O Oracle suporta os três.
PostgreSQL
SELECT city, district, SUM(balance)
FROM customer
GROUP BY GROUPING SETS ((city, district), (city), ());
-- CUBE produces all subset combinations
SELECT city, district, SUM(balance)
FROM customer
GROUP BY CUBE(city, district);O PostgreSQL 9.5+ suporta ROLLUP, CUBE e GROUPING SETS em conformidade com o padrão. A função GROUPING() indica se uma coluna está em uma linha de total (NULL). HAVING filtra após a agregação; WHERE, antes.
MySQL
SELECT city, COUNT(*) AS n
FROM customer
GROUP BY city
HAVING n > 5;
-- ROLLUP in MySQL:
SELECT city, district, SUM(balance)
FROM customer
GROUP BY city, district WITH ROLLUP;O MySQL/MariaDB geram subtotais/totais gerais com a sintaxe GROUP BY ... WITH ROLLUP; CUBE e GROUPING SETS não são suportados. Aliases do SELECT podem ser usados no HAVING (isso geralmente não funciona no Oracle/SQL Server). Nas linhas de ROLLUP, a coluna agrupada aparece como NULL.
SQL Server
SELECT city, COUNT(*) AS n
FROM customer
GROUP BY city
HAVING COUNT(*) > 5;
-- ROLLUP / CUBE / GROUPING SETS
SELECT city, district, SUM(balance)
FROM customer
GROUP BY ROLLUP(city, district);Junto com o GROUP BY, o SQL Server suporta ROLLUP(), CUBE() e GROUPING SETS (2008+) com sintaxe moderna; a antiga forma WITH ROLLUP/WITH CUBE está obsoleta. GROUPING() e GROUPING_ID() ajudam a distinguir as linhas de total.
MongoDB
// Closest equivalent: $group + $sum
db.customer.aggregate([
{ $group: { _id: "$city", n: { $sum: 1 } } },
{ $match: { n: { $gt: 5 } } }
])
// $facet is used for ROLLUP-like multi-level totalsNo MongoDB, $group é o equivalente ao GROUP BY do SQL; _id define a chave de agrupamento e os acumuladores ($sum, $avg, $max) definem as agregações. A filtragem após o agrupamento é feita com $match (o equivalente ao HAVING). Totais em vários níveis, como ROLLUP/CUBE, são obtidos executando vários pipelines com $facet.
Redis
# Not applicable: core Redis has no GROUP BY.
# Aggregation with RediSearch:
FT.AGGREGATE customer_idx "*" GROUPBY 1 @city REDUCE COUNT 0 AS nO Redis core não oferece agrupamento; o comando FT.AGGREGATE do módulo RediSearch faz agregação semelhante ao SQL com GROUPBY e REDUCE (COUNT, SUM, AVG). A etapa FILTER filtra o resultado agrupado como um HAVING. Sem o módulo, a agregação é feita na aplicação.
Elasticsearch
GET customer/_search
{
"size": 0,
"aggs": {
"by_city": { "terms": { "field": "city" },
"aggs": { "total": { "sum": { "field": "balance" } } } }
}
}No Elasticsearch, o agrupamento é feito com a bucket aggregation 'terms' e as agregações com metric aggregations (sum, avg, cardinality). Para filtragem semelhante a HAVING, use a pipeline aggregation 'bucket_selector'. Subtotais em vários níveis são montados com agregações aninhadas.