SQL 日常工作总结

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 ;

你可能感兴趣的:(SQL 日常工作总结)