DBAtlas · 数据库运维图谱

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 按给定列对行分组并应用聚合函数;HAVING 过滤分组后的结果(WHERE 在分组前过滤行)。ROLLUP 生成层次化小计 + 总计,CUBE 生成所有组合,GROUPING SETS 生成所选的分组。Oracle 三者均支持。

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);

PostgreSQL 9.5+ 以符合标准的方式支持 ROLLUP、CUBE 和 GROUPING SETS。GROUPING() 函数可判断某列是否处于汇总行(NULL)。HAVING 在聚合后过滤,WHERE 在聚合前过滤。

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;

MySQL/MariaDB 通过 GROUP BY ... WITH ROLLUP 语法生成小计/总计;不支持 CUBE 和 GROUPING SETS。HAVING 中可以使用 SELECT 别名(这在 Oracle/SQL Server 中通常不可行)。在 ROLLUP 行中,分组列显示为 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);

除 GROUP BY 外,SQL Server 以现代语法支持 ROLLUP()、CUBE() 和 GROUPING SETS(2008+);旧的 WITH ROLLUP/WITH CUBE 形式已弃用。GROUPING() 和 GROUPING_ID() 有助于区分汇总行。

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 totals

在 MongoDB 中,$group 等价于 SQL GROUP BY;_id 设置分组键,累加器($sum、$avg、$max)定义聚合。分组后的过滤通过 $match 完成(等价于 HAVING)。ROLLUP/CUBE 之类的多级汇总可通过 $facet 运行多个管道获得。

Redis

# Not applicable: core Redis has no GROUP BY.
# Aggregation with RediSearch:
FT.AGGREGATE customer_idx "*" GROUPBY 1 @city REDUCE COUNT 0 AS n

核心 Redis 不提供分组;RediSearch 模块的 FT.AGGREGATE 命令通过 GROUPBY 和 REDUCE(COUNT、SUM、AVG)执行类似 SQL 的聚合。FILTER 步骤像 HAVING 一样过滤分组结果。没有该模块时,聚合需在应用中完成。

Elasticsearch

GET customer/_search
{
  "size": 0,
  "aggs": {
    "by_city": { "terms": { "field": "city" },
      "aggs": { "total": { "sum": { "field": "balance" } } } }
  }
}

在 Elasticsearch 中,分组通过 'terms' 桶聚合完成,聚合计算通过指标聚合(sum、avg、cardinality)完成。类似 HAVING 的过滤使用 'bucket_selector' pipeline 聚合。多级小计通过嵌套聚合构建。

在 DBAtlas 中打开 →