S02006

错误代码

S02006

报错信息

When joining multiple tables, only the first table to be joined can be a partitioned table. RefId:S02006

错误原因

使用函数嵌套方式进行多表 join 时,只允许在最外层的 join 中使用分布式表。如果除最外层 join 的表外,还有 join 中使用了分区表,则会报这个错误。例如,以下例子执行时会报错:

dbName = "dfs://test_multi_table_join"
if(existsDatabase(dbName)){
	dropDatabase(dbName)
}
db = database(dbName, VALUE, 1..3)

t1 = table(1..3 as id)
t2 = table(1..3 as id)
t3 = table(1..3 as id)

pt1 = db.createPartitionedTable(t1, `pt1, `id)
pt2 = db.createPartitionedTable(t1, `pt2, `id)
pt3 = db.createPartitionedTable(t1, `pt3, `id)
pt1.append!(t1)
pt2.append!(t2)
pt3.append!(t3)

//内层 ej 的两个表 pt2 和 pt3 都是分布式表,所以会报错
select * from ej(pt1, ej(pt2, pt3, `id), `id)
//内层 ej 中使用了分布式表 pt2,所以会报错
select * from ej(t1, ej(pt2, t3, `id), `id)
//以下两行代码,都因为内层 ej 中使用了分布式表 pt1 和 pt2,出现会报错
select * from ej(ej(pt1, pt2, `id), pt3, `id)
select * from ej(ej(pt1, pt2, `id), t3, `id)

解决办法

  • 对于 2.00.10 之前的版本,需要把内层 join 的分区表数据通过 select 取到内存后再进行 join。
  • 对于 2.00.10 及以后的版本,使用标准 SQL 写法。

以下是 2.00.10 及以后的版本,对上面 4 个查询使用标准 SQL 进行改写,不会再出现报错:

select * from pt1 inner join (select * from pt2 inner join pt3 on pt2.id=pt3.id) tmp on pt1.id=tmp.id
select * from t1 inner join (select * from pt2 inner join t3 on pt2.id=t3.id) tmp on t1.id=tmp.id
select * from pt1 inner join pt2 on pt1.id=pt2.id inner join pt3 on pt2.id=pt3.id
select * from pt1 inner join pt2 on pt1.id=pt2.id inner join t3 on pt2.id=t3.id