mysql常用语句与函数大全及举例

 更新时间:2026年01月07日 11:23:27   作者:海马  
文章主要介绍了MySQL查询语句的执行顺序,包括FROM、WHERE、GROUP BY、HAVING、SELECT、ORDER BY和LIMIT等子句的使用方法,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

各个子句的执行顺序

了解mysql的查询语句的执行顺序,会对编写sql语句有一定的帮助。

  • from子句:基于表进行查询操作
  • where子句:进行条件筛选或者条件过滤
  • group by子句:对剩下的数据进行分组查询。
  • having子句:分组后,再次条件筛选或过滤
  • select子句:目的是选择业务需求的字段进行显示
  • order by子句:对选择后的字段进行排序
  • limit子句:进行分页查询,或者是查询前n条记录

where子句

where关键字后,用于书写筛选的条件。条件可以是:

1、比较运算:  = < <= = != <>

2、逻辑连接  : AND(同时满足) OR(满足其一)

3、区间 :         BETWEEN … AND … 等价于 ≥ 且 ≤
                           NOT BETWEEN … AND … 等价于 < 或 >

4、集合匹配 :   IN (…) 在列表内任一值
                            NOT IN (…) 不在列表内所有值   

                            ALL (…) 大于集合中最大值
                           ANY (…) 大于集合中最小值

                        (MySQL 中 ALL/ANY 仅子查询可用)

5、模糊匹配  :  LIKE '_abc%' _ 任意 1 字符,% 任意 0+ 字符

6、空值判断  :  IS [NOT] NULL

group by子句

  1. count (column name|常量|*)  返回每组中的总记录数
  2. sum (column namel常量)        返回每组中指定字段的值的总和
  3. avg (column name)                返回每组中指定字段的值的平均值
  4. max (column name)                返回每组中指定字段的值的最大值
  5. min (column name)                返回每组中指定字段的值的最小值

having子句

使用了group by子句后,再次对数据进行筛选和过滤,筛选的条件与where相同

distinct关键字

  • 置于列名前。
    • 当select子句中有多个字段时,distinct必须要位于第一个字段的前面,表示这些字段的值的组合进行去重。
    • 也可以位于函数中指定字段的第一个字段前面

order by子句

它的执行时机是在select子句后执行,通常用于对查询出来的数据进行排序的。

order by colName [asc|desc] [,colName [asc|desc]]...

asc:表示根据指定字段的值升序排序,是默认值,可以省略不写。

desc:表示根据指定字段的值降序排序。

可以指定多个字段,分别进行排序。当前一个字段的值相同时,后一个字段的排序规则才会生效。

limit关键字

当查询出来的数据量过大,导致当前屏幕不能一次性全部展示出来时,我们可以使用limit关键字进行限制条数查询。

limit [off,] size;

size:表示要查询的数量

off参数: 表示从第几条记录开始查询, 记录的索引从0开始的。 如果没有该参数,表示从第一条开始查询size条。

常用函数

数值函数

函数

函数说明

pow(x,y)/power(x,y)

返回x的y次幂

sqrt(n)

返回非负数n的平方根

pi()

返回圆周率

rand()、rand(n)

返回在范围0到1.0内的随机浮点值(可以使用数字n作为初始值)

truncate(n,d)

保留数字n的d位小数并返回

least(x,y,...)、greatest(x,y,...)

求最小值或最大值

mod(n,m)

取模运算,返回n被m除的余数

ceil(n)、ceiling(n)、floor(n)

向上/向下取整函数

round(n[,d])

返回n的四舍五入值,保留d位小数(d的默认值为0)

日期函数

函数

函数说明

curdate()\curtime()\now()\sysdate()\current_timestamp()

获取系统时间

dayofweek(date) \weekday(date) \dayname(date)

获取星期几

dayofmonth(date) \dayofyear(date) \monthname(date)

获取第几天

year(date)\month(date)\day(date) \ hour(date) \minute(date) \second(date)

获取时间分量

date_format(date,format) (%Y年 %m月 %d日 %h时 %i分 %s秒 %p上下午 %W星期)

日期格式化,根据format字符串格式化date的值

date_add(date,interval value unit) \date_sub(date,interval value unit)

日期运算

adddate(date,interval value unit) \subdate(date,interval value unit)

日期运算

其他函数

单条件分支函数:if

语法:if(express,value1,value2):

解析:如果express表达式成立,就返回value1,否则返回value2.

多条件分支函数:case

写法1
case  column_name 
    when value1 then returnValue1  
    when value2 then returnValue2 
    ...
    else returnValueN end;
写法2
case  
when condition1 then returnValue1  
when condition2 then returnValue2 
...
else returnValueN end;

窗口函数

窗口函数介绍

窗口函数,也被称为分析函数,是 MySQL 8.0 引入的一项强大功能 ,它能够在查询结果集中对数据进行分组、排序和计算,而无需使用临时表或自连接。窗口函数的语法结构如下:

window_function(expr) OVER ([PARTITION BY partition_expression, ...]
[ORDER BY sort_expression [ASC | DESC], ...])

window_function有如下分类:

能类型

函数名

应用场景

聚合类

SUM, AVG, COUNT、max、min

对窗口内的数据进行聚合计算

排名类

ROW_NUMBER, RANK, DENSE_RANK

对数据进行排序并生成排名

分布类

PERCENT_RANK, CUME_DIST

计算分布情况

偏移类

LAG, LEAD

获取上下行数据

over函数解析

OVER() 函数是 窗口函数(Window Function) 的一部分,用于在查询中执行基于一组的行计算,同时保留这些行的原始记录。这与传统的聚合函数(如 SUM()、AVG() 等)不同,后者通常会将多行合并为一行输出。

  • PARTITION BY: 将数据划分为多个逻辑分区(类似GROUP BY),每个分区独立计算
  • ORDER BY: 定义窗口内行的排序方式,影响如累计、排名等计算顺序

排名函数

  • 2)row_number()
  • 给排序过的表记录分配行号,从1开始的连续自然数
  • 3)rank()
  • 给排序过的表记录分配名次。 相同的值名次一样,后续的排名出现跳跃情况
  • 4)dense_rank()
  • 给排序过的表记录分配名次。 相同的值名次一样,后续的排名不出现跳跃情况

关联查询

关联分类

分类

语法

解析

内连接

table_name [inner] join table_name on condition

返回满足条件的记录组合

左外连接

table_name left [outer] join table_name on condition

左表为主表,除了返回满足条件的记录组合外,左表中剩余记录也返回,右表字段以null形式占位。

右外连接

table_name right [outer] join table_name on condition

右表为主表,除了返回满足条件的记录组合外,右表中剩余记录也返回,左表字段以null形式占位。

交叉连接

在使用join连接或者逗号连接查询,但是没有使用on或where关键字来指定关联条件时,就会出现交叉连接

这种交叉连接,产生的记录数为两张表的记录数的乘积,这种结果也被称之为笛卡尔积

union [all]操作符

如果我们想要将两个查询的结果集合并到一起,我们就可以使用union [all] 操作符。

select  column_name,column_name,.... from table_name 
union [all]
select  column_name,column_name,.... from table_name 
  • union all:两个子句中的重复部分,会保留,不去重。
  • union:会去掉并集中的重复记录

子查询

有的时候,当一个查询语句A所需要的数据,不是直观在表中体现,而是另外一个查询语句B查询出来的结果,那么查询语句A就是主查询语句,查询语句B就是子查询语句。这种查询我们称之为高级关联查询,也叫做子查询。

子查询语句的位置可以在wherefromhavingselect这四种子句中。

列题

--建表
--学生表
CREATE TABLE `Student`(
        `s_id` VARCHAR(20),
        `s_name` VARCHAR(20) NOT NULL DEFAULT '',
        `s_birth` VARCHAR(20) NOT NULL DEFAULT '',
        `s_sex` VARCHAR(10) NOT NULL DEFAULT '',
        PRIMARY KEY(`s_id`)
);
--课程表
CREATE TABLE `Course`(
        `c_id`  VARCHAR(20),
        `c_name` VARCHAR(20) NOT NULL DEFAULT '',
        `t_id` VARCHAR(20) NOT NULL,
        PRIMARY KEY(`c_id`)
);
--教师表
CREATE TABLE `Teacher`(
        `t_id` VARCHAR(20),
        `t_name` VARCHAR(20) NOT NULL DEFAULT '',
        PRIMARY KEY(`t_id`)
);
--成绩表
CREATE TABLE `Score`(
        `s_id` VARCHAR(20),
        `c_id`  VARCHAR(20),
        `s_score` INT(3),
        PRIMARY KEY(`s_id`,`c_id`)
);
--插入学生表测试数据
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女');
--课程表测试数据
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');
insert into Course values('04' , '体育' , '01');
--教师表测试数据
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');
--成绩表测试数据
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);
-- 1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数   
select st.s_id , st.s_name , s1.s_score a1 ,  s2.s_score a2
		from student st 
				LEFT join score s1 on st.s_id = s1.s_id AND s1.c_id = '01'   
				LEFT JOIN score s2 on st.s_id = s2.s_id AND s2.c_id = '02'
						where s1.s_score IS NOT NULL 
								AND	s1.s_score > COALESCE(s2.s_score, 0); 
-- 2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数
select st.s_id , st.s_name , s1.s_score a1,  s2.s_score a2
		from student st 
				LEFT join score s1 on st.s_id = s1.s_id AND s1.c_id = '01'
				LEFT JOIN score s2 on st.s_id = s2.s_id AND s2.c_id = '02'
						where COALESCE(s1.s_score, 0)  < COALESCE(s2.s_score, 0)
3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
select st.s_id , st.s_name , avg(sc.s_score)AS avg_score
		from student st
				JOIN score sc on st.s_id = sc.s_id
						group by st.s_id, st.s_name
								HAVING AVG(sc.s_score) >= 60;
SELECT 
    st.s_id, 
    st.s_name, 
    AVG(sc.s_score) AS avg_score
FROM 
    Student st
JOIN 
    Score sc ON st.s_id = sc.s_id
GROUP BY 
    st.s_id, st.s_name
HAVING 
    AVG(sc.s_score) >= 60;
4、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩
                 (包括有成绩的和无成绩的)
SELECT 
    st.s_id, 
    st.s_name, 
    AVG(sc.s_score) 平均成绩
FROM 
    Student st
LEFT JOIN 
    Score sc ON st.s_id = sc.s_id
GROUP BY 
    st.s_id, st.s_name						 
HAVING 
    AVG(sc.s_score) < 60 or AVG(sc.s_score) is NULL ;						 
5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
SELECT  
	st.s_id,
	st.s_name,
	count(sc.c_id),
	SUM(sc.s_score)
FROM 
	student st LEFT JOIN score sc on st.s_id=sc.s_id
GROUP BY st.s_id;
6、查询"李"姓老师的数量 
SELECT
		count(0)
from
		teacher
WHERE
		t_name LIKE '李%';
7、查询学过"张三"老师授课的同学的信息 
SELECT
	st.s_id,st.s_name,st.s_birth,st.s_sex
FROM
	student st
	JOIN score  sc on st.s_id=sc.s_id
	JOIN course c on sc.c_id=c.c_id
	JOIN teacher t on c.t_id=t.t_id
WHERE
	t.t_name='张三'
GROUP BY st.s_id;
8、查询没学过"张三"老师授课的同学的信息 
SELECT *
FROM student 
WHERE s_id not in (SELECT sc.s_id
		FROM score  sc 
			JOIN course c on sc.c_id=c.c_id
			JOIN teacher t on c.t_id=t.t_id
		WHERE t.t_name ='张三' GROUP BY sc.s_id ); 
SELECT *
FROM student 
	WHERE s_id not in (SELECT st.s_id
FROM student st
	JOIN score  sc on st.s_id=sc.s_id
	JOIN course c on sc.c_id=c.c_id
	JOIN teacher t on c.t_id=t.t_id
WHERE
	t.t_name='张三'
GROUP BY st.s_id
	 ); 
9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
SELECT
	st.s_id,st.s_name,st.s_birth,st.s_sex
FROM
	student st
	JOIN score s1 on st.s_id=s1.s_id and s1.c_id='01' 
	JOIN score s2 on st.s_id=s2.s_id and s2.c_id='02' 
10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
SELECT st.* FROM
	student st
	JOIN score s1 on st.s_id=s1.s_id and s1.c_id='01'
	WHERE st.s_id NOT IN (
		SELECT
			st.s_id
		FROM
			student st
			JOIN score s2 on st.s_id=s2.s_id and s2.c_id='02');
11、查询没有学全所有课程的同学的信息
SELECT st.* FROM
	student st 
	WHERE st.s_id NOT IN (
	SELECT st.s_id FROM
	student st 
		JOIN score s1 on st.s_id=s1.s_id and s1.c_id='01'
	WHERE st.s_id IN (
		SELECT st.s_id FROM student st
			JOIN score s2 on st.s_id=s2.s_id and s2.c_id='02')
		AND st.s_id  in (
		SELECT st.s_id FROM student st
			JOIN score s3 on st.s_id=s3.s_id and s3.c_id='03'))
SELECT st.* 
FROM student st 
LEFT JOIN score sc on st.s_id=sc.s_id
GROUP BY st.s_id
HAVING COUNT(1)<3;
12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息 
SELECT *
FROM student st
JOIN score s2 on st.s_id=s2.s_id
WHERE st.s_id <> '01' AND s2.c_id in(
SELECT s.c_id
FROM score s WHERE s.s_id='01') 
GROUP BY st.s_id;                                                            
SELECT s.c_id
FROM score s WHERE s.s_id='01';
13、查询和"01"号的同学学习的课程完全相同的其他同学的信息 
SELECT st.*
FROM Student st
JOIN (
    SELECT s_id,COUNT(*)AS cnt,                -- 该生修的课程门数
            GROUP_CONCAT(c_id ORDER BY c_id) AS courses -- 课程按字典序拼成串
    FROM Score
    GROUP BY s_id
     ) t ON st.s_id = t.s_id
WHERE st.s_id <> '01'                         -- 排除 01 自己
  AND t.cnt = (SELECT COUNT(*) FROM Score WHERE s_id = '01')        -- 门数相同
  AND t.courses = (SELECT GROUP_CONCAT(c_id ORDER BY c_id)
                   FROM Score WHERE s_id = '01');                   -- 课程串相同
14、查询没学过"张三"老师讲授的任一门课程的学生姓名 
SELECT t.s_name
FROM student t
WHERE t.s_id not in(
			SELECT s.s_id
			FROM score s
			WHERE s.c_id in(
						SELECT c_id 
						FROM teacher t 
						JOIN course c on t.t_id=c.t_id
						WHERE t.t_name='张三'));
			SELECT s.s_id
			FROM score s
			WHERE s.c_id in(
						SELECT c_id 
						FROM teacher t 
						JOIN course c on t.t_id=c.t_id
						WHERE t.t_name='张三');
SELECT c_id 
FROM teacher t 
JOIN course c on t.t_id=c.t_id
WHERE t.t_name='张三';
15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
SELECT t.s_id ,t.s_name,avg(s.s_score)
FROM student t
join score s on t.s_id=s.s_id
WHERE s.s_score<60
GROUP BY s.s_id
HAVING  count(0)>=2;
SELECT s.s_id
FROM score s
WHERE s.s_score<60
GROUP BY s.s_id
HAVING  count(0)>=2;
16、检索"01"课程分数小于60,按分数降序排列的学生信息
SELECT t.*,s.s_score
FROM student t
join score s on t.s_id=s.s_id and c_id='01'
WHERE s.s_score<60
order by s.s_score DESC;
17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
SELECT
    st.s_id,
    st.s_name,
    MAX(CASE WHEN sc.c_id = '01' THEN sc.s_score END) AS 语文,
    MAX(CASE WHEN sc.c_id = '02' THEN sc.s_score END) AS 数学,
    MAX(CASE WHEN sc.c_id = '03' THEN sc.s_score END) AS 英语,
    ROUND(AVG(sc.s_score), 2) AS avg_score
FROM Student st
JOIN Score sc ON st.s_id = sc.s_id
GROUP BY st.s_id, st.s_name
ORDER BY avg_score DESC;

到此这篇关于mysql常用语句与函数大全及举例的文章就介绍到这了,更多相关mysql常用语句内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql中varchar类型的日期进行比较、排序等操作的实现

    mysql中varchar类型的日期进行比较、排序等操作的实现

    在mysql使用过程中,日期一般都是以datetime、timestamp等格式进行存储的,但有时会因为特殊的需求或历史原因,日期的存储格式是varchar,那么应该怎么进行比较和排序等问题,本文就来介绍一下
    2021-11-11
  • 浅谈innodb的索引页结构,插入缓冲,自适应哈希索引

    浅谈innodb的索引页结构,插入缓冲,自适应哈希索引

    下面小编就为大家带来一篇浅谈innodb的索引页结构,插入缓冲,自适应哈希索引。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • mysql字符集和校对规则(Mysql校对集)

    mysql字符集和校对规则(Mysql校对集)

    字符集的概念大家都清楚,校对规则很多人不了解,一般数据库开发中也用不到这个概念,mysql在这方便貌似很先进,大概介绍一下
    2012-07-07
  • 详解MySQL存储过程参数有三种类型(in、out、inout)

    详解MySQL存储过程参数有三种类型(in、out、inout)

    MySQL 存储过程参数有三种类型:in、out、inout。它们各有什么作用和特点呢
    2012-07-07
  • MySQL 按指定字段自定义列表排序的实现

    MySQL 按指定字段自定义列表排序的实现

    下面小编就为大家带来一篇MySQL 按指定字段自定义列表排序的实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • Mysql事务索引知识汇总

    Mysql事务索引知识汇总

    这篇文章主要介绍了Mysql事务索引知识汇总,mysql事务是用于处理操作量大、复杂性高的数据,索引能加快数据库的查询速度并高效获取指定的数据,下文相关详细内容,需要的小伙伴可以参考一下
    2022-03-03
  • MySQL中NULL和空值的区别及说明

    MySQL中NULL和空值的区别及说明

    这篇文章主要介绍了MySQL中NULL和空值的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • mysql group by having 实例代码

    mysql group by having 实例代码

    mysql中group by语句用于分组查询,可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表, 经常和having一起使用,需要的朋友可以参考下
    2016-11-11
  • MySQL无法修改主键的问题分析及解决方案

    MySQL无法修改主键的问题分析及解决方案

    最近同事咨询了一个问题,TDSQL(for MySQL)中的某张表主键需要改为联合主键,是否必须先删除现有的主键?因为删除主键时,提示这个错误,所以本文给大家介绍了MySQL无法修改主键的问题分析及解决方案,需要的朋友可以参考下
    2024-01-01
  • MySql开发之自动同步表结构

    MySql开发之自动同步表结构

    这篇文章主要给大家介绍了关于MySql开发之自动同步表结构的相关资料,这样可以避免在开发中由于修改数据库字段导致的数据库表不一致问题,需要的朋友可以参考下
    2021-05-05

最新评论