MySQL-常用SQL汇总
参考文献
- MySQL按日期分组统计(按天统计,按月统计)
- mysql查询今天、昨天、7天、近30天、本月、上一月 数据
- SQL进阶教程–[日] MICK
- Divided We Stand: The SQL of Relational Division
- High Performance Relational Division in SQL Server
按日期分组统计
-
按月统计
1
2
3
4
5
6
7SELECT
date_format( create_time, '%Y-%m' ) date,
count(*) num
FROM
table_name
GROUP BY
date_format( create_time, '%Y-%m' ); -
按天统计
1
2
3
4
5
6
7SELECT
date_format( create_time, '%Y-%m-%d' ) date,
count(*) num
FROM
table_name
GROUP BY
date_format( create_time, '%Y-%m-%d' );
MySQL查询日期数据
-
今天
1
2
3SELECT *
FROM 表名
WHERE to_days(时间字段名) = to_days(now()); -
昨天
1
2
3SELECT *
FROM 表名
WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) <= 1 -
最近7天
1
2
3SELECT *
FROM 表名
WHERE DATE_SUB( CURDATE(), INTERVAL 7 DAY ) <= date( 时间字段名) ); -
近30天
1
2
3SELECT *
FROM 表名
WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(时间字段名) -
本月
1
2
3SELECT *
FROM 表名
WHERE DATE_FORMAT( 时间字段名, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' ) -
上一月
1
2
3SELECT *
FROM 表名
WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( 时间字段名, '%Y%m' ) ) =1 -
本季度
1
2
3SELECT *
FROM 表名
WHERE QUARTER ( 时间字段名 )= QUARTER (now()) -
上季度
1
2
3SELECT *
FROM 表名
WHERE QUARTER(时间字段名) = QUARTER(DATE_SUB(now(),interval 1 QUARTER)); -
本年
1
2
3SELECT *
FROM 表名
WHERE YEAR ( 时间字段名 )= YEAR (NOW()); -
上年
1
2
3SELECT *
FROM 表名
WHERE YEAR ( 时间字段名 )= YEAR (DATE_SUB(now(),interval 1 YEAR); -
当前这周
1
2
3SELECT *
FROM 表名
WHERE YEARWEEK(date_format(时间字段名,'%Y-%m-%d')) = YEARWEEK(now()); -
上周
1
2
3SELECT *
FROM 表名
WHERE YEARWEEK(date_format(时间字段名,'%Y-%m-%d')) = YEARWEEK(now()) - 1; -
距离当前N个月的数据
1
2
3SELECT *
FROM 表名
WHERE 时间字段名 BETWEEN date_sub( now(), INTERVAL N MONTH ) AND now();
自连接
-
自连接经常和非等值连接结合起来使用.
-
自连接和
GROUP BY
结合使用可以生成递归集合. -
将自连接看作不同表之间的连接更容易理解.
-
应把表看作行的集合,用面向集合的方法来思考.
-
自连接的性能开销更大,应尽量给用于连接的列建立索引
删除重复行
1 | mysql> select * from user; |
1 | mysql> DELETE |
ERROR 1093
: 不能先SELECT
出同一表中的某些值,再UPDATE
这个表(同一语句中)
1 | DELETE |
1 | DELETE |
1 | -- 删除重复行的高效SQL语句:通过NOT IN求补集 |
查找局部不一致的列
1 | mysql> select * from Addresses; |
1 | SELECT DISTINCT |
排序
1 | create table goods( |
- 注意 的地方,与多表之间进行的普通连接相比,自连接的性能开销更大(特别是与非等值连接结合使用的时候),因此用于自连接的列推荐使用主键或者在相关列上建立索引
NULL
SQL 三值逻辑
-
NULL
不是值. -
因为
NULL
不是值,所以不能对其使用谓词 -
对
NULL
使用谓词后的结果是unknown
. -
unknown
参与到逻辑运算时,SQL 的运行会和预想的不一样. -
按步骤追踪 SQL 的执行过程能有效应对 4 中的情况.
NOT IN
和NOT EXISTS
不是等价的
HAVING
HAVING
子句是可以单独使用的(相当于对空字段进行了GROUP BY
操作).
判断序列是否连续
1 | SELECT |
- 若查询结果有1行,则表示序列不连续;如查询结果为空,则表示序列连续;
查询缺失编号的最小值
1 | SELECT |
用HAVING
子句进行子查询: 求众数
- 众数(Mode)是指在统计分布上具有明显集中趋势点的数值,代表数据的一般水平. 也是一组数据中出现次数最多的数值,有时众数在一组数中有好几个.用M表示.
1 | -- 求众数的 SQL语句 (1):使用谓词 |
用HAVING
子句进行自连接: 求中位数
- 中位数指的是将集合中的元素按升序排列后恰好位于正中间的元素. 如果集合的元素个数为偶数,则取中间两个元素的平均值作为中位数.
1 | -- 求中位数的SQL语句: 在HAVING子句中使用非等值自连接 |
查询不包含NULL
的集合
- COUNT函数的使用方法有 COUNT(*)和 COUNT(列名)两种,它们的区别有两个:第一个是性能上的区别;第二个是 COUNT(*)可以用于NULL,而 COUNT(列名 )与其他聚合函数一样,要先排除掉 NULL的行再进行统计. 第二个区别也可以这么理解:COUNT(*)查询的是所有行的数目,而 COUNT(列名 )查询的则不一定是.
1 | mysql> select * from t; |
查询用户最近一次生日
1 | SELECT |
存储过程
1 | CREATE TABLE nums ( a INT UNSIGNED NOT NULL PRIMARY KEY ) ENGINE = InnoDB; |
示例
统计一张表中每条记录所占字节的平均值
1 | mysql> desc orders; |
1 | SELECT |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HoleLin's Blog!