这两天写了一下多表查询的sql语句,然后把14年做天猫推荐竞赛写的sql翻出来看看,还是很有借鉴作用的。
一、sum/case when…then…else…end
表结构如下:
user_id | brand_id | type | visit_datetime |
a | 1 | 0 | 2000/1/11 |
b | 2 | 0 | 2000/1/11 |
c | 3 | 1 | 2000/1/11 |
d | 6 | 2 | 2000/1/11 |
e | 7 | 1 | 2000/1/11 |
1.1 查询在一个时间段内某一列某个数出现的次数之和
方法一(用count):
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;
方法二(用sum,case when..then..else..end):
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
<span style="font-size:14px;">group by user_id , brand_id ;</span>
注:case 只能和一对else,end出现;when…then..可以写多组。
下面是一段比较复杂的逻辑,大概描述的就是将type=0的记录按照时间进行打分得到和grade,然后按照其降序排列,且输出限制1000:
select user_id, brand_id,(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
<strong>group by</strong> user_id , brand_id
<strong>order by</strong> type0 desc
)a
order by grade desc <strong>limit</strong> 1000;
二、多表查询
2.1 join..on
select a.user_id,a.brand_id from
(
SELECT * FROM first_15
)a
<strong>join</strong>
(
select * from first_20
)b
<strong>on</strong> a.user_id = b.user_id and a.brand_id = b.brand_id and a.type = b.type and a.visit_datetime = b.visit_datetime
group by user_id,brand_id;
SELECT a.user_id , a.brand_id FROM
(
select user_id , brand_id from user_behavior_all
)a
<strong>join</strong>
(
select user_id , brand_id , type from t_alibaba_data
)b
where a.user_id = b.user_id and a.brand_id = b.brand_id and b.type = 1
group by user_id , brand_id;
2.2 left join
以左表为基准,右表只会留下左表有的,除去右表没有的,两个表结合join但不是合并merge。
select a.user_id , a.brand_id , b.flag
from first_20 a left join first_15_flag b
on a.user_id = b.user_id and a.brand_id = b.brand_id
group by user_id , brand_id;
2.3 三表join
select tmp.a, tmp.b , case when t3.a is null then 0 else 1 end as flag from
(
SELECT t1.a,t1.b FROM
(
select * from T1
)t1
left join
(
select * from T2
)t2
on t1.a = t2.a and t1.b = t2.b
)tmp
left join
(
select * from T3
)t3
on tmp.a = t3.a and tmp.b = t3.b ;<strong>
</strong>
select * from
(
select a.client_id from
(select client_id, role_id from qcs_client_role)a
JOIN
(select role_id from qcs_configure where entry='shdx7' and storage_unit='sh_mams_cold')b
where a.role_id = b.role_id
)c
JOIN
(select * from qcs_client)d
where c.client_id = d.id;
2.4 inner join
求两个表交集的个数:
SELECT count(distinct c1,c2) FROM one inner join two using(c1,c2);
三、用一个sql语句来区别distinct和group by
·select count(distinct user_id) from t_alibaba_data;(选出不同user_id的总数,结果只有一个数)
·select count(*) from t_alibaba_data group by user_id;(选出不同的user_id对应的行总数,结果多行)
四、选择表a中的数据然后新建表b,在表b中添加一列属性”finished”并置零
drop table if exists objects_to_delete;
create table objects_to_delete AS
(
SELECT * FROM `objects`
where name like "%user/hive/warehouse%"
);
alter table objects_to_delete
add finished int default 0;
五、获取指定时间间隔的数据DATE_ADD()
DATE_ADD用法:http://www.w3school.com.cn/sql/func_date_add.asp
有个需求就是获取前三个月以外的数据:
<pre name="code" class="sql">select * from table_name
where create_time >= DATE_ADD(NOW(),INTERVAL -3 MONTH) ;
当然如果是获取前三个月的数据只需要改一下比较箭头就行了:
select * from table_name
where create_time >= DATE_ADD(NOW(),INTERVAL -3 MONTH) ;
六、删除表中与其他表级联的内容
table:student
id | name |
1 | Jack |
2 | Rose |
3 | Lily |
table:grade
name | score |
Jack | 80 |
删除grade表中名为Jack所在student表中的信息:
delete from student
where exists
(
select a.* from
(
select * from student
)a
join
(
select name from grade
where name="Jack"
)b
on a.name = b.name
);
Author:忆之独秀
Email:leaguenew@qq.com
注明出处:http://blog.csdn.net/lavorange/article/details/51088924