一、核心规则
·非聚合列强制分组:在 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 的商品及其销售次数:
SELECT ss_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 个商品:
SELECT ss_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;
六、可以在 GROUP BY 中使用别名吗?
是的,TCHouse-X 支持在 GROUP BY 中引用 SELECT 列表中定义的别名。
七、为什么我的分组结果比预期多?
请检查数据中是否存在不可见的空格或空值。如前文所述,TCHouse-X 会将它们视为不同的组。