今天客戶提了一個小需求,希望我能提供一條sql語句,幫助他對數據中 _field 這個欄位的值去重,並且保留其他欄位的數據。第一反應是select distinct,但這種語句在對某個欄位去重時,無法保留其他欄位,所以select distinct不成立。因為用戶對去重沒有要求,欄位值重覆時保留任意 ...
今天客戶提了一個小需求,希望我能提供一條sql語句,幫助他對數據中 _field 這個欄位的值去重,並且保留其他欄位的數據。第一反應是select distinct,但這種語句在對某個欄位去重時,無法保留其他欄位,所以select distinct不成立。因為用戶對去重沒有要求,欄位值重覆時保留任意一行就行,所以我想到當欄位值重覆時,選出對應主鍵最大的那條數據作為保留數據,這樣可以實現用戶的去重需求。但是用戶的表中又沒有主鍵,沒辦法,我們只好先使用視窗函數創建主鍵了。
因為平時喜歡用hive on spark寫sql,所以sql語句使用中間表的形式來寫,_field為去重欄位,other_fields為原表table中_field外的其他欄位
1.創建主鍵(存在主鍵則無需創建,視窗函數需要遍歷所有行數據,數據量大時會很慢)
TEMP table1 = select row_number() over (order by _field) as id, _field, other_fields from table
2.選出每個_field對應的最大主鍵
TEMP table2 = select max(id) as max_id from table1 group by _field
3.找出選中的主鍵對應的原表數據
TEMP table3 = select _field, other_fields from table2 left join table on table2.max_id = table1.id
OUTPUT table3
中間表寫法看起來可能有些亂,對於mysql這種支持嵌套查詢的資料庫來說,寫起來更好理解
id為主鍵,_field為去重欄位,other_fields為原表table中_field外的其他欄位
select * from table where id in (select max(id) from table group by _field);