select兼容性
query:
select:
SELECT [ ALL | DISTINCT ]
{ * | projectItem [, projectItem ]* }
FROM tableExpression
[ WHERE booleanExpression ]
[ GROUP BY { groupItem [, groupItem ]* } ]
[ HAVING booleanExpression ]
selectWithoutFrom:
SELECT [ ALL | DISTINCT ]
{ * | projectItem [, projectItem ]* }
projectItem:
expression [ [ AS ] columnAlias ]
| tableAlias . *
tableExpression:
tableReference [, tableReference ]*
| tableExpression [ NATURAL ] [ ( LEFT | RIGHT | FULL ) [ OUTER ] ] JOIN tableExpression [ joinCondition ]
| tableExpression CROSS JOIN tableExpression
| tableExpression [ CROSS | OUTER ] APPLY tableExpression
joinCondition:
ON booleanExpression
| USING '(' column [, column ]* ')'
tableReference:
tablePrimary
[ [ AS ] alias [ '(' columnAlias [, columnAlias ]* ')' ] ]
|tablePrimary:
[ [ catalogName . ] schemaName . ] tableName
'(' TABLE [ [ catalogName . ] schemaName . ] tableName ')'
|values:
VALUES expression [, expression ]*
groupItem:
expression
| '(' ')'
| '(' expression [, expression ]* ')'
SELECT UNION [ALL | DISTINCT] SELECT ...
when case语法
CASE case_value
WHEN booleanExpression THEN expression
[WHEN booleanExpression THEN expression] ...
[ELSE expression]
END CASE
单表,全局表
对于分片表
不支持with子句,以后可能会支持
生成的sql模板会带有for update语句,在涉及多个存储节点的时候,sql执行的锁的范围比所需单节点sql的大,所以尽量编写查询单节点的sql,一般就是select …from where ……for update
不支持select into outfile
不支持select use/ignore index
不支持 STRAIGHT_JOIN和 NATURAL JOIN
不支持有歧义的别名
如此错误
SELECT t.user_id FROM db1.travelrecord t GROUP BY id; Expression ‘t.user_id’ is not being grouped 修改成 SELECT any_value(t.user_id) FROM db1.travelrecord t GROUP BY id;
projectItem被group by的引用的无聚合函数的字段需要使用any_value
order by必须引用select item中存在的字段
子查询需要带有别名
project Item不支持相同的字段名
limit,offset不能超过2147483647且大于等于0
别名会在同一层次的select item中生效,覆盖原来的
库名.表名.字段
尤其是聚合函数
select count(xxx.id),id as id2 from xxx;//count(xxx.id)找不到
而且使用别名后,外层查询请使用别名,
select count(xxx.id),id as id2 from xxx;
此时id2马上生效,导致id找不到
select id from (select id as id2 from xxx) ...
外层id找不到
具体异常可能是这样的
Exception in thread "main" java.lang.NullPointerException
at org.apache.calcite.sql2rel.SqlToRelConverter.convertIdentifier(SqlToRelConverter.java:3983)
at org.apache.calcite.sql2rel.SqlToRelConverter.access$2400(SqlToRelConverter.java:221)
group_concat替代方案
group_concat只有在命中一个分片/分区的时候有正确结果,涉及多个分片/分区的时候不会进行结果集合拼的
https://blog.csdn.net/gaoyunshan163/article/details/106620445/
涉及到in的表达式,不建议in里面嵌套子查询,建议把子查询拆分出来一个单独sql,查询后把结果再拼接到新的sql的in表达式里
JOIN的写法
https://www.yuque.com/ccazhw/ml3nkf/sm28mz
重构查询方式
例如下面这个查询:SELECT * FROM tab JOIN tag_post ON tag_post.tag_id=tag.id JOIN post ON tag_post.post_id=post.id WHERE tag.tag='mysql';
可以分解成下面的这些查询来代替:SELECT * FROM tag WHERE tag='mysql'; SELECT * FROM tag_post WHERE tag_id=1234; SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);
原链接:https://www.cnblogs.com/xlzfdddd/p/10130493.html
有些JOIN会导致全表扫描,可以使用BKAJOIN解决,但是建议的使用方式是,参考BKAJOIN生成的执行计划,然后在业务代码里面使用上述的重构查询方式消除掉这个JOIN
使用BKAJOIN(in)解决右表没有分片条件的分片表的join
https://www.yuque.com/ccazhw/ml3nkf/rtiywf
BKAJOIN(values))解决右表是单表或者全局表的join
https://www.yuque.com/ccazhw/ml3nkf/gpla7m