問題解決:Only SubQuery expressions that are top level conjuncts are allowed

問題場景

CDHhue界面控制檯上面,使用hive組件,執行較爲複雜的SQLSQL內含有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

解決方案

既然已經知道問題的原因,那麼就很好解決了。我提供以下兩種方式:

  1. 使用 union allor條件的語句切割成兩條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
    
  2. 使用 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

大家看到這裏,如果我的文章可以對大家產生幫忙,麻煩在文章底部點個贊或者收藏;如果有好的討論,也可以留言。謝謝大家的觀看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章