本文将从标准SQL的角度出发,列举您在使用MaxCompute SQL时的常见问题。

MaxCompute SQL与其它SQL基本区别

主要区别 问题现象 解决办法
应用场景 不支持事务(不支持Commit和Rollback,不推荐使用Insert Into)。 建议代码具有幂等性支持重跑,推荐Insert Overwrite写入数据。
不支持索引和主外键约束。
不支持自增字段和默认值。 如果有默认值,请在数据写入时自行赋值。
表分区 单表最多支持6万个分区。分区超过6万个会报错。 选择合适的分区列,减少分区数。
一次查询输入的分区不能超过1万,否则执行会报错;如果是2级分区且查询时只根据2级分区进行过滤,总的分区数大于1万也可能导致报错。 解决方案请参见执行SQL语句时,报错输出表的分区过多,如何处理?
精度 DOUBLE类型存在精度问题。 不建议在关联时候进行直接使用等号关联两个DOUBLE字段。建议将两个数相减,如果差距小于一个预设的值就认为是相同,例如abs(a1- a2) < 0.000000001
虽然MaxCompute支持高精度的类型DECIMAL,但是存在更高精度的需求。 如果有更高精度要求的,可以先把数据存为 STRING类型,然后使用UDF来实现对应的计算。
数据类型转换 各种预期外的错误,代码维护问题。 如果有2个不同的字段类型需要执行Join操作,建议您先把执行类型转换再执行Join操作。
日期型和字符串的隐式转换。 在需要传入日期型的函数里如果传入一个字符串,字符串和日期类型根据yyyy-mm-dd hh:mi:ss格式进行转换。

DDL与DML的区别及解决办法

主要区别 问题现象 解决办法
表结构 不能修改分区列列名,只能修改分区列对应的值。 解决方案请参见MaxCompute中分区和分区列的区别是什么?
支持增加列,但是不支持删除列以及修改列的数据类型。 解决方案请参见SQL常见问题
INSERT MaxCompute SQL需要在Insert Into/Overwrite后加关键字Table。
数据插入表的字段映射不是根据Select的别名执行的,而是根据Select字段的顺序和表中字段的顺序执行映射的。
UPDATE/DELETE 目前不支持Update/Delete语句。 解决方案请参见如何更新和删除数据?
SELECT MaxCompute SQL最多支持6张小表的MapJoin,并且连续Join的表不能超过16张。 解决方案请参见执行MaxCompute SQL时,报错输入表过多,如何处理?
一个非分组列同一个Group By Key中的数据有多条,不使用聚合函数无法展示。 Group By查询中的Select字段,应是Group By的分组字段,或者需要使用聚合函数。
子查询 子查询必须要有别名。 建议查询不要带别名。
IN/NOT IN In/Not In,Exist/Not Exist,后面的子查询数据量不能超过1000条。 解决方案请参见如何使用Not In?
如果业务上已经保证了子查询返回结果的唯一性,可以考虑去掉Distinct,从而提升查询性能。
SQL返回10000条 MaxCompute限制了单独执行Select语句时返回的数据条数。 解决方案请参见其他操作
需要查询的结果数据条数很多。 解决方案请参见使用SQLTask进行SQL查询时,若查询结果条数大于限制的1000条,该如何获取所有数据?
MAPJOIN Join不支持笛卡尔积。 Join必须要用ON关键字设置关联条件。
如果有一些小表要作为广播表,需要使用Mapjoin Hint。
解决方案请参见如何解决Join报错?
ORDER BY Order By后面需要配合Limit N使用。 如果希望执行大数据量的排序任务,甚至是全表排序任务,可以设置较大的N值。
解决方案请参见MaxCompute中,查询出来的数据是根据什么排序的?
UNION ALL 参与UNION ALL运算的所有表必须列数一致,否则抛出异常。 参与UNION ALL运算的所有列的数据类型、列个数、列名称必须完全一致。
UNION ALL查询外面需要再嵌套一层子查询。