當使用SQL提升數字時,表中經常會有重復的值。例如,如果我們想要獲得uv(獨立訪問者),我們需要進行重復數據刪除。
在Mysql中,通常使用distinct或group by子句,但在支持窗口函數的sql(如Hive SQL、Oracle等)中。),row_number窗口函數也可用于重復數據刪除。
舉個栗子,還有這樣一個表任務:
備注:
Task_id:任務id;
Order_id:訂單id;
Start_time:開始時間
注意:一個任務對應多個訂單。
我們需要找到任務的總數,因為task_id不是唯一的,所以我們需要消除重復:
distinct
-列出task_id的所有唯一值(重復數據刪除后的記錄)
- selectdistincttask_id
-from task;
-任務總數
selectcount(distincttask_id)任務編號
fromTask
Distinct通常效率很低。它不適合顯示重復數據刪除后的具體值,通常與count一起使用來計算條形數。
當使用distinct時,它被放置在select之后,并且它后面的所有字段的值被統一進行重復數據消除。例如,如果distinct之后有兩個字段,則兩條記錄1,1和1,2不是重復值。
group by
-列出task_id的所有唯一值(重復數據刪除后的記錄,null也是一個值)
-選擇任務標識
-來自任務
-group by task _ id;
-任務總數
selectcount(任務標識)任務編號
從(選擇任務標識號
來自任務
group bytask _ id)tmp;
row_number
Row_number是一個窗口函數,語法如下:
Row_number()over(用于分組的partitionby字段名orderby用于組內排序的字段名)
其中可以省略部分分割。
-在支持窗口函數的sql中使用
select count(casewhenrn=1 tentask _ idelsenullend)task _ num
從(選擇任務標識號
,row _ number()over(partitionbytask _ idorderbystart _ time)rn
from task)tmp;
此外,在表測試的幫助下,我們可以管理distinct和group by在去加權中的使用:
-底部的分號;用于分隔行。
選擇distinctuser_id
fromTest-返回1;2
selectdistinctuser用戶標識,用戶類型
fromTest-返回1,1;1,2;2,1
選擇用戶標識
來自測試
groupbyuser _ id-返回1;2
選擇用戶標識,用戶類型
來自測試
groupbyuser_id,user _ type-返回1,1;1,2;2,1
選擇用戶標識,用戶類型
來自測試
groupbyuser _ id
- Hive,Oracle等。將報告錯誤。mysql可以這樣寫。
-返回1,1或1,2;2,1(共兩行)。只有group by之后的字段才會重復,也就是說最終返回的記錄數等于前面sql中的記錄數,也就是兩條記錄。
-不放在groupby之后而是放在select中的字段將只返回一條記錄(就好像它通常是第一條記錄,這應該是不規則的)
原文