AWK好文 及 常用統計分析SQL在AWK中的實現

呆呆笨笨的魚發表於2015-09-25
不過一堆臨時資料這樣從 mysql 導來導去還是挺麻煩的,比較理想的選擇是本機裝個 cygwin
環境,然後可以用 awk 等 shell 工具做即時處理。

本文主要講述如何在 awk 中實現 SQL 的常用操作,當做個簡單的 awk 入門分享。
雖然文中部分 awk 會有其它更簡潔高效的 shell 命令去完成,亦或是其它語言去完成,
但這都不在本文的討論範疇。

注:本文所用到的兩個測試檔案 user、consumer,分別模擬兩張 SQL 表:

user 表,欄位:
id name  addr

1 zhangsan hubei
3 lisi tianjin
4 wangmazi guangzhou
2 wangwu beijing

consumer 表,欄位:
id cost date

1 15 20121213
2 20 20121213
3 100 20121213
4 99 20121213
1 25 20121114
2 108 20121114
3 100 20121114
4 66 20121114
1 15 20121213
1 115 20121114

測試環境
OS 版本:
uname -a
CYGWIN_NT-6.1 june-PC 1.7.9(0.237/5/3) 2011-03-29 10:10 i686 Cygwin
awk 版本:
awk --version
GNU Awk 3.1.8

1、查詢整張表記錄,where 條件過濾,關鍵詞:where
select * from user; awk 1 user;
select * from consumer where cost > 100;
awk '$2>100' consumer


2、對某個欄位去重,或者按記錄去重,關鍵詞:distinct
select distinct(date) from consumer;
awk '!a[$3]++{print $3}' consumer
select distinct(*) from consumer;
awk '!a[$0]++' consumer


3、記錄按序輸出,關鍵詞:order by
select id from user order by id;
awk '{a[$1]}END{asorti(a);for(i=1;i<=length(a);i++){print a[i]}}' user


4、取前多少條記錄,關鍵詞:limit
select * from consumer limit 2;
awk 'NR<=2' consumer
awk 'NR>2{exit}1' consumer # performance is better


5、分組求和統計,關鍵詞:group by、having、sum、count
select id, count(1), sum(cost) from consumer group by id having count(1) > 2;
awk '{a[$1]=a[$1]==""?$2:a[$1]","$2}END{for(i in a){c=split(a[i],b,",");if(c>2){sum=0;for(j in b){sum+=b[j]};print i"\t"c"\t"sum}}}' consumer


6、模糊查詢,關鍵詞:like(like屬於通配,也可正則 REGEXP)
select name from user where name like 'wang%';
awk '$2 ~/^wang/{print $2}' user
select addr from user where addr like '%bei';
awk '/.*bei$/{print $3}' user
select addr from user where addr like '%bei%';
awk '$3 ~/bei/{print $3}' user


7、多表 join 關聯查詢,關鍵詞:join
select a.* , b.* from user a inner join consumer b  on a.id = b.id and b.id = 2;
awk 'ARGIND==1{a[$1]=$0;next}{if(($1 in a)&&$1==2){print a[$1]"\t"$2"\t"$3}}' user consumer


8、多表水平聯接,關鍵詞:union all
select a.* from user a union all select b.* from user b;
awk 1 user user
select a.* from user a union select b.* from user b;
awk '!a[$0]++' user user


9、隨機抽樣統計,關鍵詞:order by rand()
SELECT * FROM consumer ORDER BY RAND() LIMIT 2;
awk 'BEGIN{srand();while(i<2){k=int(rand()*10)+1;if(!(k in a)){a[k];i++}}}(NR in a)' consumer


10、行列轉換,關鍵詞:SUM(IF())、WITH ROLLUP
mysql 寫法:
http://my.oschina.net/leejun2005/blog/77796
  awk 寫法: />

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28929558/viewspace-1809403/,如需轉載,請註明出處,否則將追究法律責任。

相關文章