在 hive ParseException 上使用 OR

问题描述

所以我试图将 ddl 从 odi(oracle 数据集成)转移到 hive。

代码如下:

(308 row of code,there are fppnonday,dtddyr subquery before )
...
LEFT OUTER JOIN 
  (SELECT * FROM dffo
    WHERE 1 = 1 
    AND dffo.date = '20100909')dffot 
ON fppnonday.B_ACCT = dffot.B_CODE
where ( from_unixtime(unix_timestamp(dffot.START_DATE,'yyyyMMdd')) <= dtddyr.FULL_DATE
AND from_unixtime(unix_timestamp(dffot.END_DATE,'yyyyMMdd')) <= dtddyr.FULL_DATE
AND (dffot.C_CODE = '000' OR dffot.NAG = 'Y'))

LEFT OUTER JOIN 
  (SELECT * FROM  dflagw
    WHERE 1 = 1 
    AND dflagw.date = '20100909')dflagwr
ON fppnonday.CUER = dflagwr.CER
AND from_unixtime(unix_timestamp(dflagwr.START_DATE,'yyyyMMdd')) <= dtddyr.FULL_DATE
AND from_unixtime(unix_timestamp(dflagwr.END_DATE,'yyyyMMdd')) > dtddyr.FULL_DATE
;

当我运行所有查询时,出现错误: ParseException:在 ')' 附近的 LEFT 处缺少 EOF 它指的是第二个 LEFT OUTER JOIN

出了什么问题?如何有效且高效地使用 OR?

任何想法/帮助总是不胜感激!

解决方法

您可以使用 AND 代替 WHERE,以便将这些条件组合到 ON 条件中:

LEFT OUTER JOIN 
  (SELECT * FROM dffo
    WHERE 1 = 1 
    AND dffo.date = '20100909')dffot 
ON (fppnonday.B_ACCT = dffot.B_CODE)
AND ( from_unixtime(unix_timestamp(dffot.START_DATE,'yyyyMMdd')) <= dtddyr.FULL_DATE
AND from_unixtime(unix_timestamp(dffot.END_DATE,'yyyyMMdd')) <= dtddyr.FULL_DATE
AND (dffot.C_CODE = '000' OR dffot.NAG = 'Y'))

LEFT OUTER JOIN 
  (SELECT * FROM  dflagw
    WHERE 1 = 1 
    AND dflagw.date = '20100909')dflagwr
ON fppnonday.CUER = dflagwr.CER
AND from_unixtime(unix_timestamp(dflagwr.START_DATE,'yyyyMMdd')) <= dtddyr.FULL_DATE
AND from_unixtime(unix_timestamp(dflagwr.END_DATE,'yyyyMMdd')) > dtddyr.FULL_DATE
;

或者您可以按照评论的建议将 where 语句放在最后:

LEFT OUTER JOIN 
  (SELECT * FROM dffo
    WHERE 1 = 1 
    AND dffo.date = '20100909')dffot 
ON fppnonday.B_ACCT = dffot.B_CODE

LEFT OUTER JOIN 
  (SELECT * FROM  dflagw
    WHERE 1 = 1 
    AND dflagw.date = '20100909')dflagwr
ON fppnonday.CUER = dflagwr.CER
AND from_unixtime(unix_timestamp(dflagwr.START_DATE,'yyyyMMdd')) > dtddyr.FULL_DATE

where ( from_unixtime(unix_timestamp(dffot.START_DATE,'yyyyMMdd')) <= dtddyr.FULL_DATE
AND (dffot.C_CODE = '000' OR dffot.NAG = 'Y'))
;