我有一个Oracle查询,该查询正在获取2500万条记录,没有pk或没有适当分配的列以按列拆分的列。因此,我考虑过使用ROW_number() over () as RANGEGROUP
来创建一个序列号。但是当我使用这个伪列时,它给了我一个错误的提示
org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:164)上的引起原因:java.sql.SQLSyntaxErrorException:ORA-00904:“ P”。“ RANGEGROUP”:oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:91)处的标识符无效。
我正确地给了别名,即使我在伪列中没有别名也尝试过,它仍然给出相同的错误。 我们可以在Sqoop中使用派生列拆分方式,还是该列应物理存在于表中?
答案 0 :(得分:0)
使用子查询包装row_number计算,然后在split-by中使用派生列。
--query "select col1, ... colN, RANGEGROUP
from (select t.*, row_number() OVER (order by t.item_id ) AS RANGEGROUP
from table t ) s
where 1=1 and \$CONDITIONS"
row_number
应该是确定性的,这意味着当多次执行时,它应该为所有行分配完全相同的数字。如果 OVER 中的 ORDER BY 不包含唯一的列或组合,会发生什么情况:row_number
可以为相同的行返回不同的数字。如果你在 split-by 中使用它,你会得到重复,因为同一行可以在拆分范围 1 中,比如 1-100,在 mapper2 中 sqoop 将使用范围 2 的过滤器执行相同的查询,比如 (101-200 ) 同一行也可以出现在该范围内。 Sqoop 在具有不同条件的不同容器(映射器)中运行相同的查询以并行获取分割范围。
如果 Id 是 int(如果均匀分布会更好),使用该 ID。为什么您可能需要 row_number 是因为它是 STRING 列。读这个:https://stackoverflow.com/a/37389134/2700344,分列不一定是PK