深入浅出数据分析
以此写下读第一遍的感想,大体内容就是给一些数据然后进行一些思维上面的讲解,从中收获就是没有最优解,只有最合适的解决方法。读下来的感觉还是很不错的。
其中比较专业的技术也讲的很通俗易懂,大体内容就是样本拆分,深入数据,如果这数据给不了什么结果则继续细化。区别两个很难判断的东西的时候添加一些时间特性越近越精确,找出共性。有机会接触这方面的任务会继续深入学习和考虑他们的思考逻辑方法。
1 | cut -d '"' -f 10 08-03-2015_09_36_28_AM_TRM_WW_NFS_Gamescom_Trailer_AUG15_20150803.txt|sort -k1,1|uniq -c |
uniq的使用参数的含义如下
– c 显示输出中,在每行行首加上本行在文件中出现的次数。它可取代- u和- d选项。
– d 只显示重复行。
– u 只显示文件中不重复的各行。
– n 前n个字段与每个字段前的空白一起被忽略。一个字段是一个非空格、非制表符的字符串,彼此由制表符和空格隔开(字段从0开始编号)。
+n 前n个字符被忽略,之前的字符被跳过(字符从0开始编号)。
– f n 与- n相同,这里n是字段数。
– s n 与+n相同,这里n是字符数。
忽然就想写一下来练习自己的awk和sed等语句。
1 | file=a sed "s/\"//g" $file |awk -F "," '{if($3=="Y") print($2"_RUN")}'>aa filename=`awk '{print $1}' aa` for f in $filename do >$f done rm aa |
当然还有好多种方法,我这个估计是比较简陋的一种了.
1 | sort -r xxx |
1 | sort -u xxx |
1 | sed 's/a/b/g' filename |
1 | #if without End, the script will run every time, otherwise only once |
cut的使用格式
cut [-bn] [file] 或 cut [-c] [file] 或 cut [-df] [file]
-b字节
-c字符
-f区域1
ifconfig | cut -f -2
代表1到2行1
cut -d ' ' -f 2 跟 awk -F " " '{print $2}'
这两句意思是一样一样的。cut比较擅长一个字符间隔的文本内容
$#在linux代表的是参数的意思 -ne 代表的是不等于 -eq代表的是是否等于,只能跟数字和字符串相比。
1 | mysql> select * from ja2; |
1 | mysql> select * from stu; |
1 | mysql> select * from stu |
接下去我对这个对等的结果很好奇,是不是name对应的score,那么返回的是什么
1 | mysql> select name from stu union all select score from ja2; |
+———+
| name |
+———+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 2 |
+———+
这个是最后的结果,因为union会去重,最后的2会看不见,所以我就使用来unionall。虽然最终的结果是name,但是最后一个2的确是score上面的内容。
1 | case when Mailing_Group_Dev_Cnt <>0 then 1.000*Click_Cnt/Mailing_Group_Dev_Cnt else null end as CTR |
1 | select * from a,b |
1 | select * from a,b where a.id=b.id |
以上都会进行全表扫描。
1 | select sum(process.Target),sum(conversion.cnvrsn) from (select sum(Targeted_User_Cnt) as Target,offer_id from EADW_ADM_APP.CAMPAIGN_PROCESS where Campaign_Id='1000dq9pd69b' and lead_type_id='999' group by offer_id) process left join (select sum(email_campaign_cnvrsn_cnt) as cnvrsn,offer_id from EADW_ADM_APP.CAMPAIGN_CONVERSION where Campaign_Id='1000dq9pd69b' and lead_type_id='999' group by offer_id) conversion on conversion.offer_id=process.offer_id; |
1 | 350047,368 |
1 | Select sum(Targeted_User_Cnt) from EADW_ADM_APP.CAMPAIGN_PROCESS where Campaign_Id='1000dq9pd69b' and lead_type_id='999'; |
通过跟上司的讨论,因为两个表细致程度不是一样的,所以很容易就产生一对多的问题,这样重复数据对结果影响还是比较大的,所以我就提高维度,把我不需要关心的数据直接去除掉,不降低维度是因为比较麻烦,而去意义并不大。
groupby根据2个字段中数据范围比较大的来对此进行分组。可以将两个细致程度不一样的表进行数据的统计,可以防止一对多,然后对总的数据进行groupby,这样就可以获得自己想要的数据。
1 | select Pr.Lead_Type_Id, sum(Email_Delivered_Cnt), sum(Targeted_User_Cnt), |
以上是为上司的sql语句,对于我的sql语句rightjoin和leftjoin没啥区别,过去笼统,需要更多数据的话则需要改动。groupby后跟数字的话代表的是select后面的字段顺序。
在groupby的having语句中,是闲where出来之后对group后的结果在进行having过滤。在groupby中可以直接这样使用1
select a,b from table group by 1,2
但是不能直接在having后面这样用数字来替换ab,会报string类型和number类型的错误
关于以下语句成功执行出我想要的结果,left join的时候最好把数据较多的表放在左表当中,我用right join的时候给我的数据并不完整,其中缘由我需要整理一下。
sql的执行顺序为from后面的表与join先执行,那么就是两表直接连接,接着通过on来限制对接的数据列,然后where对结果进行筛选,然后进行groupby来分组之后进行选出。1
$ select case when conversion.offer_Id='1000dm0bj6gq' then 'PS4' else 'PS3' end as Collateral,sum(conversion.email_campaign_cnvrsn_cnt),sum(process.Targeted_User_Cnt) from EADW_ADM_APP.CAMPAIGN_PROCESS process left join EADW_ADM_APP.CAMPAIGN_CONVERSION conversion on conversion.Campaign_Id=process.Campaign_Id and conversion.offer_Id=process.offer_Id and conversion.Segment_Id=process.Segment_Id and conversion.Step_Order_Nbr=process.Step_Order_Nbr and conversion.Step_Id=process.Step_Id and conversion.Country_Code=process.Country_Code and conversion.Campaign_Collection_Id=process.Campaign_Collection_Id and conversion.Generation_Date=process.Generation_Date and conversion.Lead_Type_Id=process.Lead_Type_Id where process.Campaign_Id='1000dm0bj63b' and process.lead_type_id='999' group by process.offer_Id;
以前写的sql,on跟的限制条件不多,所以对接的时候有一堆重复数据,如果没有约束的时候,仅用普通的列相对接的话,要考虑好限制条件。