select兼容性

  1. query:
  2. select:
  3. SELECT [ ALL | DISTINCT ]
  4. { * | projectItem [, projectItem ]* }
  5. FROM tableExpression
  6. [ WHERE booleanExpression ]
  7. [ GROUP BY { groupItem [, groupItem ]* } ]
  8. [ HAVING booleanExpression ]
  9. selectWithoutFrom:
  10. SELECT [ ALL | DISTINCT ]
  11. { * | projectItem [, projectItem ]* }
  12. projectItem:
  13. expression [ [ AS ] columnAlias ]
  14. | tableAlias . *
  15. tableExpression:
  16. tableReference [, tableReference ]*
  17. | tableExpression [ NATURAL ] [ ( LEFT | RIGHT | FULL ) [ OUTER ] ] JOIN tableExpression [ joinCondition ]
  18. | tableExpression CROSS JOIN tableExpression
  19. | tableExpression [ CROSS | OUTER ] APPLY tableExpression
  20. joinCondition:
  21. ON booleanExpression
  22. | USING '(' column [, column ]* ')'
  23. tableReference:
  24. tablePrimary
  25. [ [ AS ] alias [ '(' columnAlias [, columnAlias ]* ')' ] ]
  26. |tablePrimary:
  27. [ [ catalogName . ] schemaName . ] tableName
  28. '(' TABLE [ [ catalogName . ] schemaName . ] tableName ')'
  29. |values:
  30. VALUES expression [, expression ]*
  31. groupItem:
  32. expression
  33. | '(' ')'
  34. | '(' expression [, expression ]* ')'
  35. SELECT UNION [ALL | DISTINCT] SELECT ...

when case语法

  1. CASE case_value
  2. WHEN booleanExpression THEN expression
  3. [WHEN booleanExpression THEN expression] ...
  4. [ELSE expression]
  5. END CASE

单表,全局表

支持with子句
会转发sql

对于分片表

不支持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中生效,覆盖原来的

  1. 库名.表名.字段

尤其是聚合函数

  1. select count(xxx.id),id as id2 from xxx;//count(xxx.id)找不到

而且使用别名后,外层查询请使用别名,

  1. select count(xxx.id),id as id2 from xxx;
  2. 此时id2马上生效,导致id找不到
  3. select id from (select id as id2 from xxx) ...
  4. 外层id找不到

具体异常可能是这样的

  1. Exception in thread "main" java.lang.NullPointerException
  2. at org.apache.calcite.sql2rel.SqlToRelConverter.convertIdentifier(SqlToRelConverter.java:3983)
  3. 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