1.如何找出第二名?
#偏移法 limit offset(快)
select distinct Salary as SecondHighestSalary
from Employee
order by Salary desc
limit 1
offset 1
#排除法 先找到最大值,再找小于最大值的数据中的最大值(慢)
select max(Salary) as SecondHighestSalary
from Employee
where Salary< (select max(Salary) from Employee)
2.日常固定搭配
#group by + having聚合函数做筛选只能用 having(快)
select Email from Person
group by Email
having count(Email)>1
#group by + Where 做嵌套模式(慢)
select Email from
(select Email,count(Email) as mun from Person
group by Email)a
where a.mun >1
3.#删除表 用delete
delete a.* from Person a,Person b
where a.Email=b.Email
and a.id>b.id
4.#求气温比昨天高的日期
select a.id from Weather a inner join Weather b
on a.Temperature>b.Temperature
Where datediff(a.RecordDate,b.RecordDate)=1
5.#mod 余数为1是基数,为0是偶数
select * from cinema
where mod(id,2) =1
and description <> "boring"
order by rating desc
6#求年龄
select
student.SId as 学生编号,
student.Sname as 学生姓名,
TIMESTAMPDIFF(YEAR,student.Sage,CURDATE()) as 学生年龄
from student
7#求本周过生日的学生
select
*,
week(sage) as sweek,
yearweek(sage) as yweek,
EXTRACT(week FROM Sage) as eweek,
EXTRACT(week FROM now()) as nweek
from student
where EXTRACT(week FROM Sage)=EXTRACT(week FROM now());
日期的运算
1、现有日期进行偏移(推荐)
date_sub(日期 ,要减少偏移的间隔)
date_sub(date,INTERVAL expr type)
date_add(日期 ,要增加偏移的间隔)
date_add(date,INTERVAL expr type)
expr 是要偏移的数值
type 是要偏移的方式
时间格式的转换
1、字符串转换为日期格式
str_to_date (时间字符串,字符串日期格式) :能够把字符串转换为标准日期格式
日期的格式
格式描述
%Y年,4 位
%y年,2 位
%M英文名称的月名(一月为January,二月为February)
%m数值月份 (00-12)
%D带有英文后缀的天(不太直观)
%d数值天 (00-31)
%H小时 (00-23)
%h小时 (01-12)
%I小时 (01-12)
%i分钟,数值(00-59)
%S秒(00-59)
%s秒(00-59)
%a英文缩写星期名
%b英文缩写月名
%c月,数值
%f微秒
%p显示是 AM 还是 PM
%r显示时分秒时间,12小时制(hh:mm:ss AM 或 PM)
%T显示时分秒时间, 24小时制 (hh:mm:ss)
%j显示当前日期是今年的第几天 (001-366)
eg:
select str_to_date('08/09/2008', '%m/%d/%Y'); -- 2008-08-09
select str_to_date('08/09/08' , '%m/%d/%y'); -- 2008-08-09
select str_to_date('08.09.2008', '%m.%d.%Y'); -- 2008-08-09
select str_to_date('08:09:30', '%h:%i:%s'); -- 08:09:30
select str_to_date('08.09.2008 08:09:30', '%m.%d.%Y %h:%i:%s'); --2008-08-09 08:09:30
2、日期转换为特殊字符串形式
date_format (日期,字符串格式):能够把一个日期转换为各种样式的字符串
eg:
select date_format(now(),'%Y-%M-%d %H') ; -- 2020-May-23 17
select date_format('2020-02-03 13:45:06.676','%Y-%M-%D %I:%i:%S-%T') ; --2020-February-3rd 01:45:06-13:45:06
获取当前时间
1、获取年月日时分秒
now 函数:获取当前时间信息
eg:select now();
sysdate 函数:
eg:select sysdate();
区别:
now() 在执行开始时值就得到了;
sysdate() 在函数执行时动态得到值。
eg:
select now(), sleep(3),now();
select sysdate(), sleep(3) , sysdate();
2、获取年月日
current_date 函数
eg:
select current_date();
select curdate();
3、获取时分秒
current_time 函数
eg:
select current_time();
select curtime();
日常工作需要用到Mysql数据分析的案例:
涉及表:
orderinfo 订单详情表
| orderid 订单id
| userid 用户id
| isPaid 是否支付
| price 付款价格
| paidTime 付款时间
userinfo 用户信息表
| userid 用户id
| sex 用户性别
| birth 用户出生日期
1、统计不同月份的下单人数
select
year(paidTime),
month(paidTime),
count(distinct userid) as cons
from orderinfo
where
isPaid="已支付"
andpaidTime<>'0000-00-00 00:00:00'
group byyear(paidTime),month(paidTime);
2、统计用户三月份的回购率和复购率
复购率:当月购买了多次的用户占当月用户的比例
回购率:上月购买用户中有多少用户本月又再次购买
a、先筛选出3月份的消费情况
select
*
from orderinfo
where
isPaid="已支付"
andmonth(paidTime)="03";
b、统计一下每个用户在3月份消费了多少次
select
userid,
count(1) as cons
from orderinfo
where
isPaid="已支付"
andmonth(paidTime)="03"
group by userid;
c、对购买次数做一个判断,统计出来那些消费了多次(大于1次)的用户数
select
count(1) as userid_cons,
sum(if(cons>1,1,0)) as fugou_cons,
sum(if(cons>1,1,0))/count(1) as fugou_rate
from (select
userid,
count(1) as cons
from orderinfo
where isPaid="已支付"
andmonth(paidTime)="03"
group by userid
)a;
本月回购率:本月购买用户中有多少用户下个月又再次购买
3月份的回购率= 3月用户中4月又再次购买的人数 / 3月的用户总数
a、统计每年每月的一个用户消费情况
select
userid,
date_format(paidTime,'%Y-%m-01') as month_dt,
count(1) as cons
from orderinfo
where
isPaid="已支付"
group byuserid,date_format(paidTime,'%Y-%m-01');
b、相邻月份进行关联,能关联上的用户说明就是回购
select
*
from (select
userid,
date_format(paidTime,'%Y-%m-01') as month_dt,
count(1) as cons
from orderinfo
where
isPaid="已支付"
group byuserid,date_format(paidTime,'%Y-%m-01')) a
left join (select
userid,
date_format(paidTime,'%Y-%m-01') as month_dt,
count(1) as cons
from orderinfo
where
isPaid="已支付"
group byuserid,date_format(paidTime,'%Y-%m-01')) b
ona.userid=b.userid
anddate_sub(b.month_dt,interval 1 month)=a.month_dt;
c、统计每个月份的消费人数情况及格得到回购率
select
a.month_dt,
count(a.userid) ,
count(b.userid) ,
count(b.userid) / count(a.userid)
from (select
userid,
date_format(paidTime,'%Y-%m-01') as month_dt,
count(1) as cons
from orderinfo
where
isPaid="已支付"
group byuserid,date_format(paidTime,'%Y-%m-01')) a
left join (select
userid,
date_format(paidTime,'%Y-%m-01') as month_dt,
count(1) as cons
from orderinfo
where
isPaid="已支付"
group byuserid,date_format(paidTime,'%Y-%m-01')) b
ona.userid=b.userid
anddate_sub(b.month_dt,interval 1 month)=a.month_dt
group bya.month_dt;
3、统计男女用户消费频次是否有差异
1、统计每个用户的消费次数,注意要带性别
select
a.userid,
sex,
count(1) as cons
from orderinfo a
inner join (select* from userinfo where sex<>'') b
ona.userid=b.userid
group bya.userid,sex;
2、对性别做一个消费次数平均计算
select
sex,
avg(cons) as avg_cons
from (select
a.userid,
sex,
count(1) as cons
from orderinfo a
inner join (select* from userinfo where sex<>'') b
ona.userid=b.userid
group bya.userid,sex) a
group by sex;
4、统计多次消费的用户,第一次和最后一次消费间隔是多少天
1、取出多次消费的用户
select
userid
from orderinfo
where
isPaid="已支付"
group by userid
havingcount(1)>1;
2、取出第一次和最后一次的时间
select
userid,
min(paidTime),
max(paidTime),
datediff(max(paidTime), min(paidTime))
from orderinfo
where
isPaid="已支付"
group by userid
havingcount(1)>1;
5、统计不同年龄段,用户的消费金额是否有差异
a、计算每个用户的年龄,并对年龄进行分层:0-10:1,11-20:2,21-30:3
select
userid,
birth,
now(),
timestampdiff(year,birth,now()) as age
from userinfo
wherebirth>'1900-00-00';
select
userid,
birth,
now(),
ceil(timestampdiff(year,birth,now())/10) asage
from userinfo
wherebirth>'1901-00-00';
b、关联订单信息,获取不同年龄段的一个消费频次和消费金额
select
a.userid,
age,
count(1) as cons,
sum(price) as prices
from orderinfo a
inner join (select
userid,
birth,
now(),
ceil(timestampdiff(year,birth,now())/10) asage
from userinfo
wherebirth>'1901-00-00') b
ona.userid=b.userid
group bya.userid,age;
c、再对年龄分层进行聚合,得到不同年龄层的消费情况
select
age,
avg(cons),
avg(prices)
from (select
a.userid,
age,
count(1) as cons,
sum(price) as prices
from orderinfo a
inner join (select
userid,
birth,
now(),
ceil(timestampdiff(year,birth,now())/10) asage
from userinfo
wherebirth>'1901-00-00') b
ona.userid=b.userid
group bya.userid,age) a
group by age;
6、统计消费的二八法则,消费的top20%用户,贡献了多少消费额
1、统计每个用户的消费金额,并进行一个降序排序
select
userid,
sum(price) as total_price
from orderinfo a
where
isPaid="已支付"
group by userid;
2、统计一下一共有多少用户,以及总消费金额是多少
select
count(1) as cons,
sum(total_price) as all_price
from (select
userid,
sum(price) as total_price
from orderinfo a
where
isPaid="已支付"
group by userid)a;
3、取出前20%的用户进行金额统计
select
count(1) as cons,
sum(total_price) as all_price
from (
select
userid,
sum(price) as total_price
from orderinfo a
where
isPaid="已支付"
group by userid
order bytotal_price desc
limit 17000) b ;