简单的SQL语句:计算一列中某个值的个数
2014-05-05 22:39
190 查看
这两天在参加阿里大数据竞赛,进入第二赛季要用到不少的SQL语句,现在才发现当时的数据库是白学了,今天就根据具体的需求来整理一下。可以把需求整理成为一道简单的题目,题目如下:
给定一个表t_alibaba_data:
其中:user_id代表用户,brand_id代表品牌,type代表操作的类型(0-点击,1-购买,2-收藏,3-购物车),visit_datetime即用户对品牌行为的时间(0415-0515,0516-0615,0616-0715,0716-0815四个月)。假设一共有10000条交易记录。
现在有这样的需求即:我现在需要对用户user_id对某一个品牌brand_id进行评分grade(可以理解为用户对品牌的喜爱程度),评分grade规则为用户对品牌不同类型type=0,1,2,3的操作总数,然后给这些总数乘以相应的权值grade = w0*count(type=0) + w1*count(type=1) + w2*count(type=2)+w3*count(type=3)。当然考虑到时间的因素,可以对靠后时间的点击操作提高权重,相对距离较远的点击操作降低权重,那么w0*count(type=0)可以改写成
w0*( 1*count(type=0 and 0716<=visit_datatime<=0815) + 0.8*count(type=0 and 0616<=visit_datatime<=0715) +
0.6*count(type=0 and 0516<=visit_datetime<=0615) + 0.4*count(type=0 and 0415<=visit_datetime<=0515)).现在就是要创建一个表user_brand_grade<user_id,brand_id,grade>,按照grade降序排列以便找到前1000个<user_id,brand_id>对。
Step1:首先不考虑时间的因素,首先要找到用户user_id对于某个品牌brand_id某种操作type=0/1/2/3的总次数。
结果:
![](https://img-blog.csdn.net/20140505220955078?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGF2b3Jhbmdl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
当我这么写完之后我发现type0,type1,type2,type3的值都是一样的。这非常不合理,才知道这么写是有问题的。
SQL语句count()的用法:http://www.w3school.com.cn/sql/sql_func_count.asp
可见count只能计算某一列的总数目,或者某一列符合一个条件的总数目,但不能计算某列符合多个条件的相应数目。
Step2:那么修改count成为sum加上type的条件可以做出相应的选择。
![](https://img-blog.csdn.net/20140505221053578?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGF2b3Jhbmdl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
SQL语句sum()的用法:http://www.w3school.com.cn/sql/sql_func_sum.asp
sum中是可以加表达式的,因此可以加上type的相应值。
Step3:此时不禁要想,如果当type=0的时候,要根据visit_datetime选择不同的值怎么办?在此要用到case进行条件的选择。那么就可以重写Step2的SQL语句。
![](https://img-blog.csdn.net/20140505221624203?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGF2b3Jhbmdl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
Step4:用case增加时间上的判断:
![](https://img-blog.csdn.net/20140505221922031?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGF2b3Jhbmdl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
那么就可以找到符合要求的<user_id,brand_id>对了,即最活跃的用户品牌对。
转载注明出处:http://blog.csdn.net/lavorange/article/details/25004181
给定一个表t_alibaba_data:
user_id | brand_id | type | visit_datetime |
10944750 | 13451 | 0 | 0604 |
10944750 | 13451 | 2 | 0604 |
10944750 | 13451 | 2 | 0723 |
10944750 | 13451 | 0 | 0801 |
10944750 | 13451 | 0 | 0515 |
10944750 | 13451 | 0 | 0703 |
10944750 | 13451 | 0 | 0629 |
10944750 | 13451 | 0 | 0814 |
10944750 | 21110 | 0 | 0422 |
10944750 | 1131 | 0 | 0713 |
… | … | … | … |
现在有这样的需求即:我现在需要对用户user_id对某一个品牌brand_id进行评分grade(可以理解为用户对品牌的喜爱程度),评分grade规则为用户对品牌不同类型type=0,1,2,3的操作总数,然后给这些总数乘以相应的权值grade = w0*count(type=0) + w1*count(type=1) + w2*count(type=2)+w3*count(type=3)。当然考虑到时间的因素,可以对靠后时间的点击操作提高权重,相对距离较远的点击操作降低权重,那么w0*count(type=0)可以改写成
w0*( 1*count(type=0 and 0716<=visit_datatime<=0815) + 0.8*count(type=0 and 0616<=visit_datatime<=0715) +
0.6*count(type=0 and 0516<=visit_datetime<=0615) + 0.4*count(type=0 and 0415<=visit_datetime<=0515)).现在就是要创建一个表user_brand_grade<user_id,brand_id,grade>,按照grade降序排列以便找到前1000个<user_id,brand_id>对。
Step1:首先不考虑时间的因素,首先要找到用户user_id对于某个品牌brand_id某种操作type=0/1/2/3的总次数。
SELECT user_id , brand_id , count(type=0) as type0 ,count(type=1) as type1 , count(type=2) as type2 ,count(type=3) as type3 FROM t_alibaba_data t where visit_datetime >= 415 && visit_datetime <= 715 group by user_id,brand_id;
结果:
当我这么写完之后我发现type0,type1,type2,type3的值都是一样的。这非常不合理,才知道这么写是有问题的。
SQL语句count()的用法:http://www.w3school.com.cn/sql/sql_func_count.asp
可见count只能计算某一列的总数目,或者某一列符合一个条件的总数目,但不能计算某列符合多个条件的相应数目。
Step2:那么修改count成为sum加上type的条件可以做出相应的选择。
SELECT user_id , brand_id , sum(type=0) as type0, sum(type=1) as type1, sum(type=2) as type2, sum(type=3) as type3 FROM t_alibaba_data t where visit_datetime >=515 && visit_datetime <=815 group by user_id ,brand_id;结果:
SQL语句sum()的用法:http://www.w3school.com.cn/sql/sql_func_sum.asp
sum中是可以加表达式的,因此可以加上type的相应值。
Step3:此时不禁要想,如果当type=0的时候,要根据visit_datetime选择不同的值怎么办?在此要用到case进行条件的选择。那么就可以重写Step2的SQL语句。
SELECT user_id , brand_id , sum(case when type=0 then 1 else 0 end) as type0, sum(case when type=1 then 1 else 0 end) as type1, sum(case when type=2 then 1 else 0 end) as type2, sum(case when type=3 then 1 else 0 end) as type3 FROM t_alibaba_data t group by user_id , brand_id ;结果(应该和上图相同):
Step4:用case增加时间上的判断:
select * ,(type0+type1+type2+type3) as grade from ( SELECT user_id , brand_id , sum(case when type=0 && visit_datetime >= 801 && visit_datetime<=815 then 10 when type=0 && visit_datetime >= 716 && visit_datetime<=731 then 8 when type=0 && visit_datetime >= 701 && visit_datetime<=715 then 6 when type=0 && visit_datetime >= 616 && visit_datetime<=630 then 4 when type=0 && visit_datetime >= 601 && visit_datetime<=615 then 2 when type=0 && visit_datetime >= 516 && visit_datetime<=531 then 1 else 0 end) as type0, sum(case when type=1 then 1 else 0 end) as type1, sum(case when type=2 then 2 else 0 end) as type2, sum(case when type=3 then 3 else 0 end) as type3 FROM t_alibaba_data t group by user_id , brand_id order by type0 desc )a order by grade desc limit 1000;然后得到结果:
那么就可以找到符合要求的<user_id,brand_id>对了,即最活跃的用户品牌对。
转载注明出处:http://blog.csdn.net/lavorange/article/details/25004181
相关文章推荐
- 有时候执行的oracle,sql语句要查看下性能情况,可以用这个进行下简单计算和统计
- 利用SQL语句计算库存
- Oracle sql语句简单优化
- oracle 简单sql语句
- 浅析SqlServer简单参数化模式下对sql语句自动参数化处理以及执行计划重用
- 菜鸟不可不看简单SQL语句小结
- 菜鸟不可不看简单SQL语句小结
- oralce 基础知识 ,oralce 常用简单sql语句,oracle 新手必看之一
- 使用动态SQL语句实现简单的行列转置(动态产生列)
- Oracle中简单查询、限定查询、数据排序SQL语句范例和详细注解
- 『ORACLE』 SQL语句简单应用(五)(11g)
- SQL语句的简单练习
- 简单 sql 语句 实用大全
- 计算SQL语句执行时间的方法
- 一些简单、基础的SQL语句
- 简单SQL语句小结
- sql root账户密码忘记怎么办?最简单的sql语句修改方法
- sql条件查询语句的简单实例
- 使用Java反射(Reflect)、自定义注解(Customer Annotation)生成简单SQL语句
- 简单SQL语句小结[转]