count(*)是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。
count(列名)和count(*)的区别:
count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。
group_concat()函数首先根据group by指定的列进行分组,并且用分隔符分隔,将同一个同组中的值连起来,返回一个字符串结果
group_concat([distinct] 字段名 [order by 排序字段 asc/desc] [separator '分隔符'])
说明:
select GROUP_CONCAT(name) from t_user;
select GROUP_CONCAT(name separator ';') from t_user;
select depart, GROUP_CONCAT(name separator ';') from t_user group by depart;
select depart, GROUP_CONCAT(name order by salary desc separator ';') from t_user group by depart;
select RAND(), RAND(),RAND();
select floor(RAND() * 100),floor(RAND() * 100),floor(RAND() * 100);
select * from words order by RAND() limit 5;
注意下char_length和length()的区别:
-- 1. CHAR_LENGTH(str)
select CHAR_LENGTH('hello'); -- 5
select CHAR_LENGTH('你好'); -- 2
select LENGTH('hello'); -- 5
select LENGTH('你好'); -- 6
需要全匹配:
-- 3. field()
select FIELD('a','a','b','c'); -- 1
select FIELD('a','aa','a','b','c'); -- 2
今天
select * from 表名 where to_days(时间字段名) = to_days(now());
昨天
SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) <= 1
7天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时间字段名)
近30天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(时间字段名)
本月
SELECT * FROM 表名 WHERE DATE_FORMAT( 时间字段名, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' )
上一月
SELECT * FROM 表名 WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( 时间字段名, '%Y%m' ) ) =1
#查询本季度数据
select * from `ht_invoice_information` where QUARTER(create_date)=QUARTER(now());
#查询上季度数据
select * from `ht_invoice_information` where QUARTER(create_date)=QUARTER(DATE_SUB(now(),interval 1 QUARTER));
#查询本年数据
select * from `ht_invoice_information` where YEAR(create_date)=YEAR(NOW());
#查询上年数据
select * from `ht_invoice_information` where year(create_date)=year(date_sub(now(),interval 1 year));
查询当前这周的数据
SELECT name,submittime FROM enterprise WHERE YEARWEEK(date_format(submittime,'%Y-%m-%d')) = YEARWEEK(now());
查询上周的数据
SELECT name,submittime FROM enterprise WHERE YEARWEEK(date_format(submittime,'%Y-%m-%d')) = YEARWEEK(now())-1;
查询当前月份的数据
select name,submittime from enterprise where date_format(submittime,'%Y-%m')=date_format(now(),'%Y-%m')
查询距离当前现在6个月的数据
select name,submittime from enterprise where submittime between date_sub(now(),interval 6 month) and now();
查询上个月的数据
select name,submittime from enterprise where date_format(submittime,'%Y-%m')=date_format(DATE_SUB(curdate(), INTERVAL 1 MONTH),'%Y-%m')
select * from ` user ` where DATE_FORMAT(pudate, ' %Y%m ' ) = DATE_FORMAT(CURDATE(), ' %Y%m ' ) ;
select * from user where WEEKOFYEAR(FROM_UNIXTIME(pudate,'%y-%m-%d')) = WEEKOFYEAR(now())
select *
from user
where MONTH (FROM_UNIXTIME(pudate, ' %y-%m-%d ' )) = MONTH (now())
select *
from [ user ]
where YEAR (FROM_UNIXTIME(pudate, ' %y-%m-%d ' )) = YEAR (now())
and MONTH (FROM_UNIXTIME(pudate, ' %y-%m-%d ' )) = MONTH (now())
select *
from [ user ]
where pudate between 上月最后一天
and 下月第一天
where date(regdate) = curdate();
select * from test where year(regdate)=year(now()) and month(regdate)=month(now()) and day(regdate)=day(now())
SELECT date( c_instime ) ,curdate( )
FROM `t_score`
WHERE 1
LIMIT 0 , 30
timediff:只返回时分秒
select DATEDIFF(now(),'2017-03-04'), TIMEDIFF('17:25:38','17:25:30'),TIMEDIFF('17:25:38','12:25:30'), TIMEDIFF(NOW(),'2020-03-04 17:25:30');
其中window_function是窗口函数的名称;expr是参数,有些函数不需要参数;over子句包含三个选项:
序号函数可以用来实现分组排序,并添加序号,主要有三个:
查询:
SELECT name,salary,depart,
row_number() over(partition by depart order by salary desc) as rn
from t_user ;
查询:
SELECT name,salary,depart,
rank() over(partition by depart order by salary desc) as rn
from t_user ;
结果:可以看到rank在排序的时候,如果排序字段相等,就并列排名;如果有并列的下一位排名的时候,就是去掉并列人数进行排名。
代码:
SELECT name,salary,depart,
dense_rank() over(partition by depart order by salary desc) as rn
from t_user ;
select * from
(SELECT name,salary,depart,dense_rank() over(partition by depart order by salary desc) as rn from t_user ) a
where a.rn < 3
不加PARTITION BY
表示全局排序:
SELECT name,salary,depart,row_number() over(order by salary desc) as rn from t_user ;
在窗口中每条记录动态地应用聚合函数,可以动态计算在指定的窗口内的各种聚合函数值,聚合函数主要有:
select name,salary,depart,
sum(salary) over(PARTITION by depart order by id) as all_salary
from t_user
结果:可以看到,统计的salary是根据每一组的数据进行了累加
select name,salary,depart,
sum(salary) over(PARTITION by depart order by salary) as order_salary
from t_user
select name,salary,depart,
sum(salary) over(PARTITION by depart) as order_all
from t_user
select name,salary,depart,
sum(salary) over(PARTITION by depart order by id rows BETWEEN unbounded preceding and current row) as order_all
from t_user
select name,salary,depart,
sum(salary) over(PARTITION by depart order by id rows BETWEEN 3 preceding and current row) as order_all
from t_user;
结果:可以看出于正的总和是于正上面3行加上自己的总和,不算刘云云,因为刘云云是上面四行了
select name,salary,depart,
sum(salary) over(PARTITION by depart order by id rows BETWEEN 3 preceding and 1 following) as order_all
from t_user;
select name,salary,depart,
sum(salary) over(PARTITION by depart order by id rows BETWEEN current row and unbounded following) as order_all
from t_user;
包括cume_dist和percent_rank
select name,salary,depart,
-- 把所有数据当成一组
cume_dist() over(order by salary) as r1,
-- 根据部门进行分组
cume_dist() over(PARTITION by depart order by salary) as r2
from t_user;
结果:
select name,salary,depart,
rank() over(PARTITION by depart order by salary desc) as r1,
percent_rank() over(PARTITION by depart order by salary desc) as r2
from t_user;
结果说明:即用rank排序的值减去1之后除以总数减去1之后的值
包括lag和lead
select name,salary,depart,
-- 相当于把上一行的薪资,放到了自己的那一行,用作比较来进行一些其他操作
-- 3000是给定的一个默认值,上一行的默认值,如果不给默认为null
lag(salary, 1, 3000) over(PARTITION by depart order by salary) as r1,
-- 相当于把上2行的薪资,放到了自己的那一行
lag(salary, 2) over(PARTITION by depart order by salary) as r2
from t_user;
-- lead就是下一个,不多演示
包括first_value和last_value
select name,salary,depart,join_time,
-- 到今天为止,第一个入职的薪资
first_value(salary) over(PARTITION by depart order by join_time) as r1,
-- 到今天为止,最后一个入职的薪资
last_value(salary) over(PARTITION by depart order by join_time) as r2
from t_user;
包括nth_value(expr,n),ntile(n)
select name,salary,depart,join_time,
-- 到今天为止,按照入职日期排名第二的薪资
nth_value(salary, 2) over(PARTITION by depart order by join_time) as r1,
-- 到今天为止,按照入职日期排名第三的薪资
nth_value(salary, 3) over(PARTITION by depart order by join_time) as r2
from t_user;
select name,salary,depart,join_time,
-- 根据日期把数据分为3组, 平均分配,
ntile(3) over(PARTITION by depart order by join_time) as r1,
-- 根据日期把数据分为2组,优先前面分配(即向上取整:3/2 = 2,5/2= 3,4/3= 2)
ntile(2) over(PARTITION by depart order by join_time) as r2
from t_user;