高级SQL语句简单举例

这两天写了一下多表查询的sql语句,然后把14年做天猫推荐竞赛写的sql翻出来看看,还是很有借鉴作用的。


一、sum/case when…then…else…end

表结构如下:

user_id brand_idtype visit_datetime
a102000/1/11
b202000/1/11
c312000/1/11
d622000/1/11
e712000/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

idname
1Jack
2Rose
3Lily

table:grade

namescore
Jack80

删除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 

    原文作者:SQL
    原文地址: https://blog.csdn.net/lavorange/article/details/51088924
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞