GROUP BY 子句用于将结果集划分为多个逻辑组,并对每个组执行聚合计算(如 COUNT()、SUM()、AVG()、MIN() 和 MAX())。核心规则
非聚合列强制分组:在
SELECT 列表中出现的、未参与聚合计算的所有列名,必须全部列在 GROUP BY 子句中。空值处理:TCHouse-X 对数据的区分度极高。在分组逻辑中,零长度字符串 (
"")、NULL 和 空格 (" ") 被视为三个完全不同的独立值。使用数字序号 GROUP BY
TCHouse-X 支持通过正整数来引用
SELECT 列表中的列位置,从而简化代码。对应关系:正整数表示 SELECT 输出列表中的列序号(从 1 开始),而非原始物理表的列序号。这与 MySQL、PostgreSQL 和 Doris 的行为保持一致。
截断规则:如果使用小数(如
1.1),系统会将其截断为整数(1)处理。不支持负数:使用
-1 等负数会导致错误。示例
-- 以下两者等价SELECT category, COUNT(*) FROM t1 GROUP BY category;SELECT category, COUNT(*) FROM t1 GROUP BY 1;-- 小数会被截断为整数SELECT category, COUNT(*) AS cnt FROM t1 GROUP BY 1.1; -- 等价于 GROUP BY 1-- 负数不支持SELECT category, COUNT(*) FROM t1 GROUP BY -1;-- Error: Expression 'CATEGORY' is not being grouped
浮点数分组的风险提示
在处理科学或金融数据时,需特别注意
FLOAT 或 DOUBLE 类型的列。精度不确定性:由于硬件浮点数的存储特性,它们无法精确表示所有十进制分数(例如
96.94 在底层可能存储为 96.940002441...)。分组结果偏差:当对浮点数列进行
GROUP BY 时,查询结果可能会因为这种微小的精度偏差产生“看似重复但值略有不同”的行。解决方案:
1. 使用
ROUND() 函数对列进行四舍五入后再分组。2. 使用
DECIMAL 类型存储货币或需要高精度的金融数据,以避免舍入误差。综合案例
基础聚合与排序
查找销售总数量前 5 的商品及其销售次数:
SELECTss_item_sk AS Item,COUNT(ss_item_sk) AS Times_Purchased,SUM(ss_quantity) AS Total_QuantityFROM store_salesGROUP BY ss_item_skORDER BY Total_Quantity DESCLIMIT 5;
配合 HAVING 进行结果过滤
WHERE 无法过滤聚合后的结果,必须使用 HAVING。以下查询查找销售次数 >= 100 且销售总量最低的 5 个商品:SELECTss_item_sk AS Item,COUNT(ss_item_sk) AS Times_Purchased,SUM(ss_quantity) AS Total_QuantityFROM store_salesGROUP BY ss_item_skHAVING Times_Purchased >= 100ORDER BY Total_Quantity ASCLIMIT 5;
常见问题 (FAQ)
可以在 GROUP BY 中使用别名吗?
是的,TCHouse-X 支持在
GROUP BY 中引用 SELECT 列表中定义的别名。为什么我的分组结果比预期多?
请检查数据中是否存在不可见的空格或空值。如前文所述,TCHouse-X 会将它们视为不同的组。