剛學Spark sql,今天在使用過程中遇到一個小問題。來分享一下。
在 navicat 中使用 group by 相關語句並沒出錯,但是在 squirrel sql 中報瞭如下錯誤:
Error: org.apache.spark.sql.AnalysisException: expression 'XXX.`XXXX`' is neither present in the group by, nor is it an aggregate function. Add to group by or wrap in first() (or first_value) if you don't care which value you get.;;
錯誤後面說得還挺明顯的,讓我用 first() 函數,
那麼首先我們需要知道 first() 函數是幹什麼的,
經查閱,first() 函數是分組第一個元素,與之對應的還有 last(),是分組最後一個元素。
接下來,我們來看一下我的原sql,我把表換成了 student(因爲不知道會不會有安全隱患)。
CREATE OR REPLACE TEMPORARY VIEW ip_table AS
SELECT nickname,email,create_time,create_user_ip,count(*) as ip_count from student
GROUP BY create_user_ip
ORDER BY ip_count desc
這裏我根據 create_user_ip 分組,然後想查詢出分組後的數量,以及展示出對應的暱稱、郵箱等。
想一下數據庫會進行什麼操作呢,肯定是先按 create_user_ip 分組,這樣每個 ip 對應了好幾條記錄,這些記錄的暱稱、郵箱肯定是不同的,在 mysql 中,默認展示出了第一條記錄的暱稱和郵箱,count(*)所有記錄的數量。
而在 spark sql 中就報錯了,它沒能分辨出到底要展示哪條記錄的暱稱、郵箱。
因此,我們要在這些起矛盾的維度中加 first() 函數。修改後的 sql 如下:
CREATE OR REPLACE TEMPORARY VIEW ip_table AS
SELECT first(nickname),first(email),first(create_time),create_user_ip,count(*) as ip_count from student
GROUP BY create_user_ip
ORDER BY ip_count desc
這樣就不會報錯啦~