一、标量子查询 (Scalar Subqueries)
·定义:返回结果仅为 单行单列 的子查询。
·特性:常用于聚合计算(如 MAX())。该单一值可以替换到任何需要标量值的上下文中(如比较运算符)。
·空值处理:如果子查询未匹配到任何行,结果视为 NULL。
·示例:SELECT x FROM t1 WHERE x > (SELECT MAX(y) FROM t2);
二、非关联子查询 (Non-Correlated Subqueries)
·定义:子查询内部不引用外层查询的任何表。
·执行逻辑:子查询仅计算一次,其结果集作为常量提供给外层查询遍历使用。
·示例:SELECT x FROM t1 WHERE x IN (SELECT y FROM t2);
三、关联子查询 (Correlated Subqueries)
·定义:子查询内部引用了外层查询的列。
·执行逻辑:外层查询的每一行都会驱动子查询重新计算,具有极强的动态过滤能力。
·示例:
— 查找工资高于所在部门平均水平的员工SELECT name FROM employees e1 WHERE salary > (SELECT AVG(salary) FROM employees e2 WHERE e1.dept_id = e2.dept_id);
四、语法与位置
SELECT select_list FROM table_ref [, table_ref …]table_ref ::= table_name | (select_statement)
子查询可以出现在以下位置:
1. FROM 子句:作为“派生表”或“内联视图”。
2. WHERE 子句:配合比较运算符(=、>)、[NOT] IN 或 [NOT] EXISTS。
3. HAVING 子句:用于过滤聚合后的组数据。
五、开发建议与调优
·表别名引用:如果内层和外层引用了同一张表,必须使用别名来区分列的作用域。
SELECT * FROM t1 `one` WHERE id IN (SELECT parent FROM t1 `two` WHERE `one`.parent = `two`.id);
·连接顺序控制:STRAIGHT_JOIN 提示仅作用于其所在的当前查询块。如果需要优化嵌套视图或子查询的连接顺序,需在对应的嵌套块内分别添加提示。
·性能权衡:关联子查询虽然功能强大,但在处理大数据量时可能会导致频繁的子查询评估。在性能敏感场景下,优先考虑将其重写为 JOIN 形式。
六、限制
为保证分布式执行的稳定性,TCHouse-X 对子查询施加了以下限制:
·运算符限制:标量子查询不能与 ANY、ALL 或 SOME 运算符一起使用。
·比较限制:对于 EXISTS 子句,外层与内层之间的比较必须包含至少一次相等比较。
·上下文限制:
·标量子查询仅支持数值上下文。不能用于 LIKE、REGEXP 或与 TIMESTAMP 等非数值类型的比较。
·不能在 CASE 表达式中作为比较值或返回值。
·不能用作 BETWEEN 运算符的参数。
·逻辑连接限制:子查询不能出现在 OR 连接条件的外部(即 WHERE (subquery) OR col = 1 是不允许的)。
·引用限制:在子查询中引用外层列时,必须使用完全限定名。