問題場景
在CDH
的hue
界面控制檯上面,使用hive
組件,執行較爲複雜的SQL
,SQL
內含有in
關鍵字,而in
內部是關聯其他表的結果。因爲裏面含有or
字段,導致hive
解析SQL
的時候,認爲in
的條件不是位於第一序列,然後報錯。可能說着很抽象,以下是SQL
:
select a.a1,a.a2,count(*) as num
from test1 a
where a.a3 in ('1','2') and (
a.a4 in ('2','3')
or
a.a4 not in (
select c1 from test2 c where c2 = '1'
)
)
group by a.a1,a.a2
問題環境
軟件 | 版本 |
---|---|
CDH | 5.15.1 |
hive | 1.1.0 |
問題原因
從SQL
可以看出,in
的條件是與or
的另一個條件一起當做整條SQL
的條件。然後在hive
解析當中,如果要使用 in (select * from table)
這種格式的話,那必須是將in (select * from table)
當做條件的唯一體,即下面的SQL
是可以通過驗證的
select a.a1,a.a2,count(*) as num
from test1 a
where a.a3 in ('1','2') and a.a4 not in (
select c1 from test2 c where c2 = '1'
)
group by a.a1,a.a2
解決方案
既然已經知道問題的原因,那麼就很好解決了。我提供以下兩種方式:
-
使用
union all
將or
條件的語句切割成兩條SQL
,然後結果進行拼接。如果有重複數據,記得進行過濾。樣例SQL
如下:select a.a1,a.a2,count(*) as num from test1 a where a.a3 in ('1','2') and a.a4 in ('2','3') group by a.a1,a.a2 union all select a.a1,a.a2,count(*) as num from test1 a where a.a3 in ('1','2') and a.a4 not in ( select c1 from test2 c where c2 = '1' ) group by a.a1,a.a2
-
使用
left join
語句,將匹配上的數據篩選出來。樣例SQL
如下:select a.a1,a.a2,count(*) as num from test1 a left join (select c1 from test2 c where c2 = '1') c on a.a4 = c.c1 where a.a3 in ('1','2') and ( a.a4 in ('2','3') or c.c1 is null ) group by a.a1,a.a2
以上的SQL會將匹配不上的數據篩選出來。這個方法可以參考我的另一篇博客hive 如何去除兩個表相同的部分,理論是一致的。
結果
這裏是採用了第二種做法,爲了最大限度不進行大改。最後問題得到解決。
總結
問題的出現都是有原因的,找到問題發生的原因,然後根據原因得出不同的解決的方案,選擇最有利的解決方案。之後,也要進行問題的回顧和記錄,才能將知識沉澱於心。
PS
大家看到這裏,如果我的文章可以對大家產生幫忙,麻煩在文章底部點個贊或者收藏;如果有好的討論,也可以留言。謝謝大家的觀看。