今天遇到一个 SQL 在 Hive 上正常执行,但是在 SparkSQL 上 运行没有结果的问题;
下面截取其中的一段 SQL,就是导致结果不同的子句;
SELECT S.ORGID
,S.FUNDID
,S.MONEYTYPE
,S.CUSTID
,SUM(S.STKBAL*P.LASTPRICE) MARKETVALUE
FROM martrd.STKASSET S
,centrd.STKPRICE P
WHERE P.bizDATE="20200708"
AND S.bizDATE="20200708"
AND S.STKCODE = P.STKCODE
AND S.MARKET = P.MARKET
GROUP BY S.ORGID
,S.FUNDID
,S.MONEYTYPE
,S.CUSTID;
martrd.STKASSET S ,centrd.STKPRICE P
为 Hive 表;TextInputFormat;
这里,FROM t1, t2 的表达方式为 INNER JOIN, Spark 会将下面的 WHERE 中的 STKCODE, MARKET 识别为执行计划中 Join 的 partition column,执行计划没什么问题,scan 后的 sort merge 然后是 aggr;
- 检查两个表的数据在 SparkSQL 上输出没有问题;
- 选择一个符合预期的 STKCODE 在两个表上进行过滤查询;
结果发现了问题,STKASSET 的表指定 STKCODE 返回空;检查表结构发现
CREATE EXTERNAL TABLE `martrd.STKASSET`(
...
`stkcode` char(8),
...
CREATE EXTERNAL TABLE `centrd.STKPRICE`(
...
`stkcode` string COMMENT '',
...
将 Row 用 prettyJson 输出可以看到 char(N) 的字段是补了 BLANK 的;导致两个表字段值不同;
修改SQL 为 AND trim(S.STKCODE) = P.STKCODE
,后续调整 Hive 表结构,尽量不要出现 char(N);
再看 spark-hive 的 TableReader ,感觉 Hive serde 本来就会将 char(N) 补 BLANK,HiveQL 可能是做了处理,但是 SparkSQL 没有;
- 先留着疑问以后再说;TODO