使用DQL命令查询数据(二)
SELECT语法
SELECT [ALL | DISTINCT]
{ * | table.* | [ table.field1 [ as alias1] [,table.field2 [as alias2]][,…]] }
FROM table_name [ as table_ alias ]
[left|out|inner join table_name2] #联合查询
[ WHERE … ] #指定结果需满足的条件
[ GROUP BY …] #指定结果按照哪几个字段来分组
[ HAVING …] #过滤分组的记录必须满足的次要条件
[ ORDER BY… ] #指定查询记录按一个或者多个条件排序
[ LIMIT { [ offset,] row_count | row_count OFFSET offset }] ; #指定查询的记录从哪条至哪条
/*
[] 括号代表可选的; {} 括号代表必须的;
# MySQL语句中的注释符,也可以用 /*该处为注释*/
*/
- 简单易懂版:
-- 语法:
SELECT 列名 FROM 表名 [ WHERE 条件 ] [ GROUP BY …] [ HAVING …] [ ORDER BY… ][ LIMIT ];
ORDER BY排序
- ORDER BY排序查询
- 对SELECT语句查询得到的结果,按某些字段进行排序
- 与DESC或ASC搭配使用,默认为ASC
-- 示例:
-- 排序
-- order by 字段 asc(升序——默认)|desc(降序)
select * from result
ORDER BY StudentResult desc,ExamDate desc;
MySQL的LIMIT
- LIMIT [m,]n 或 LIMIT n OFFSET m
- 限制SELECT返回结果的行数
- m 制定第一个返回记录行的偏移量
- n 制定返回记录行的最大数目
- 注意:m不指定则偏移量为0,从第一条开始返回前n条记录
LIMIT 常用于分页显示
SELECT * FROM `result` LIMIT 5 -- 返回前5条记录
SELECT * FROM `result` LIMIT 5,10 -- 返回6-15条记录
-- 示例:
-- limit
-- limit [m,]n
-- m 偏移量(从第几条开始)
-- n 最大记录数
select * from result
ORDER BY StudentResult desc,ExamDate desc limit 30,10;
子查询
- 在查询语句中的WHERE条件子句中,又嵌套了另外一个查询语句
- 注意: 嵌套查询可由多个子查询组成,求解的方式是由里及外
子查询返回的结果一般都是集合,故而建议使用 IN 关键字
子查询类型
- 列中子查询
- 单列单行
-- 示例:
select a.StudentNo,a.SubjectNo,a.StudentResult,
(select b.SubjectName from `subject` b
where b.SubjectNo=a.SubjectNo) as 课程名称 -- 子查询作为列,返回只能是单列单行
from result a;
- 表子查询
- 必须有别名
-- 示例:
select tab.*,d.GradeName from
(
select SubjectName,a.StudentNo,c.GradeId,StudentName,StudentResult from result a LEFT JOIN `subject` b
on a.SubjectNo = b.SubjectNo
LEFT JOIN student c on a.StudentNo = c.StudentNo
) tab -- 子查询作为表,但必须设置别名
LEFT JOIN grade d on tab.GradeId = d.GradeID;
- 条件子查询
- 单行单列
- 多行单列
-- 示例:
select * from result a where a.StudentResult>80
and a.SubjectNo in -- 单行单列为‘=’,多行多列为‘in’
(
select SubjectNo
from `subject` b
where b.SubjectName = "高等数学-2" or b.SubjectName = "高等数学-1"
); -- 子查询作为条件
GROUP BY分组
- 使用GROUP BY关键字对查询结果分组
- 对所有的数据进行分组统计
- 分组的依据字段可以有多个,并依次分组
- 与HAVING结合使用,进行分组后的数据筛选
-- 示例:
-- 按照不同的课程分组,分别算出其平均分、最高分和最低分,
-- 对于低于60分平均分的不予显示
-- 分组一般和聚合函数同时出现
-- GROUP BY 字段
select a.SubjectNo,b.SubjectName,
sum(a.StudentResult) sumScore,
avg(a.StudentResult) avgScore
from result a
LEFT JOIN `subject` b on a.SubjectNo = b.SubjectNo
GROUP BY SubjectNo HAVING avgScore>80 ORDER BY avgScore desc ;
表合并(UNION与UNION ALL)
- 其使用时必须使各表相对应字段名数量一致,若不足:
- 当不足的字段为数字类型,则使用 0 代替(定义个别名来使用)
- count () 方法也可用于替代,但非常不推荐
- 当不足的字段为字符串类型,则使用 ” “ 代替(定义个别名来使用)
- 表合并(UNION与UNION ALL)其运行顺序为从上至下,所以应将先显示的表放在上面的顺序
- 在表合并时,若在其连接表内写入
order by
来排序没有意义,最理想的情况是将表合并之后将其用子查询作为表来最后统一进行排序
简单示例:
CREATE TABLE tab
select * from b1
UNION ALL
select * from b2
练习示例:
-- 查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
(SELECT a.*,b.s_score as score1,c.c_name FROM student a
LEFT JOIN score b ON a.s_id = b.s_id and b.c_id = 1
LEFT JOIN course c ON b.c_id = c.c_id
GROUP BY a.s_id ORDER BY score1 desc LIMIT 1,2)
UNION ALL
(SELECT a.*,b.s_score as score2,c.c_name FROM student a
LEFT JOIN score b ON a.s_id = b.s_id and b.c_id = 2
LEFT JOIN course c ON b.c_id = c.c_id
GROUP BY a.s_id ORDER BY score2 desc LIMIT 1,2)
UNION ALL
(SELECT a.*,b.s_score as score3,c.c_name FROM student a
LEFT JOIN score b ON a.s_id = b.s_id and b.c_id = 3
LEFT JOIN course c ON b.c_id = c.c_id
GROUP BY a.s_id ORDER BY score3 desc LIMIT 1,2);
UNION
与UNION ALL
的区别:
- 1、对重复结果的处理:
UNION
在进行表链接后会去重,UNION All
不会。- 2、对排序的处理:
Union
将会按照字段的顺序进行排序;UNION ALL
只是简单的将两个结果合并后就返回。UNION ALL
要比UNION
效率高,所以,如果可以确认合并的两个结果集中不包含重复数据且不需要排序时的话,那么就使用UNION ALL。(一般UNION ALL更为常用,因为效率高,且并不应该让union进行去重,最好是UNION ALL返回后可用distinct来去重)
MySQL函数
- 数学函数
- 字符串函数
常用的字符串函数
1、LOWER(column|str):将字符串参数值转换为全小写字母后返回
mysql> select lower('SQL Course');
+---------------------+
| lower('SQL Course') |
+---------------------+
| sql course |
+---------------------+
2、UPPER(column|str):将字符串参数值转换为全大写字母后返回
mysql> select upper('Use MYsql');
+--------------------+
| upper('Use MYsql') |
+--------------------+
| USE MYSQL |
+--------------------+
3、CONCAT(column|str1, column|str2,…):将多个字符串参数首尾相连后返回
mysql> select concat('My','S','QL');
+-----------------------+
| concat('My','S','QL') |
+-----------------------+
| MySQL |
+-----------------------+
如果有任何参数为null,则函数返回null
mysql> select concat('My',null,'QL');
+------------------------+
| concat('My',null,'QL') |
+------------------------+
| NULL |
+------------------------+
如果参数是数字,则自动转换为字符串
mysql> select concat(14.3,'mysql');
+----------------------+
| concat(14.3,'mysql') |
+----------------------+
| 14.3mysql |
+----------------------+
4、CONCAT_WS(separator,str1,str2,…):将多个字符串参数以给定的分隔符separator首尾相连后返回
mysql> select concat_ws(';','First name','Second name','Last name');
+-------------------------------------------------------+
| concat_ws(';','First name','Second name','Last name') |
+-------------------------------------------------------+
| First name;Second name;Last name |
+-------------------------------------------------------+
5、LENGTH(str):返回字符串的存储长度
mysql> select length('text'),length('张三');
+----------------+------------------+
| length('text') | length('张三') |
+----------------+------------------+
| 4 | 6 |
+----------------+------------------+
注意:编码方式不同字符串的存储长度就不一样(‘张三’:utf8是6,gbk是4)
CHAR_LENGTH(str):返回字符串中的字符个数
mysql> select char_length('text'),char_length('你好');
+---------------------+-----------------------+
| char_length('text') | char_length('你好') |
+---------------------+-----------------------+
| 4 | 2 |
+---------------------+-----------------------+
6、FORMAT(X,D[,locale]):以格式‘#,###,###.##’格式化数字X(常用于金钱计数)
D指定小数位数
locale指定国家语言(默认的locale为en_US)
mysql> SELECT format(12332.123456, 4),format(12332.2,0);
+-------------------------+-------------------+
| format(12332.123456, 4) | format(12332.2,0) |
+-------------------------+-------------------+
| 12,332.1235 | 12,332 |
+-------------------------+-------------------+
mysql> SELECT format(12332.2,2,'de_DE');
+---------------------------+
| format(12332.2,2,'de_DE') |
+---------------------------+
| 12.332,20 |
+---------------------------+
参考链接: https://www.cnblogs.com/geaozhang/p/6739303.html
- 日期和时间函数
常用日期和时间函数
1、获得当前日期时间 函数
获得当前日期+时间(date + time)函数:now()
, sysdate()
(和now(一样))CURRENT_DATE()
, CURRENT_TIME()
;
select now(),CURRENT_DATE(),CURRENT_TIME();
获得当前时间戳函数: current_timestamp, current_timestamp()
mysql> select current_timestamp, current_timestamp();
+---------------------+---------------------+
| current_timestamp | current_timestamp() |
+---------------------+---------------------+
| 2022-09-02 16:54:28 | 2022-09-02 16:54:28 |
+---------------------+---------------------+
2、日期转换函数、时间转换函数
日期/时间转换为字符串函数:date_format(date,format), time_format(time,format)
mysql> select date_format('2008-08-08 22:23:01', '%Y%m%d%H%i%s'); -- '%Y%m%d%H%i%s'为要得到的格式,输多少返多少
+----------------------------------------------------+
| date_format('2022-09-02 16:54:28', '%Y%m%d%H%i%s') |
+----------------------------------------------------+
| 20220902165428 |
+----------------------------------------------------+
3、日期时间计算函数
为日期增加一个时间间隔:date_add()
,减去一个时间间隔:date_sub()
set i = now();
-- interval 为增加
select date_add(i, interval 1 day); -- add 1 day
select date_add(i, interval 1 hour); -- add 1 hour
select date_add(i, interval 1 minute); -- ...
select date_add(i, interval 1 second);
select date_add(i, interval 1 microsecond);
select date_add(i, interval 1 week);
select date_add(i, interval 1 month);
select date_add(i, interval 1 quarter);
select date_add(i, interval 1 year);
select date_add(@dt, interval -1 day); -- sub 1 day、
参考链接:https://www.cnblogs.com/ggjucheng/p/3352280.html
- 系统信息函数
- select version(); 用于查看数据库版本号
MySQL的统计函数
函数名称 | 描述 |
---|---|
COUNT( ) | 返回满足SELECT条件的记录总和数,如 SELECT COUNT()… (不建议使用,效率低) |
SUM( ) | 返回数字字段或表达式列作统计,返回一列的总和 |
AVG( ) | 通常为数值字段或表达列作统计,返回一列的平均值 |
MAX( ) | 可以为数值字段、字符字段或表达式列作统计,返回最大的值 |
MIN( ) | 可以为数值字段、字符字段或表达式列作统计,返回最小的值 |
- 示例:
-- 获得 武松 的考试次数
select b.StudentName,count(b.StudentNo) as countNumber,
sum(a.StudentResult),avg(a.StudentResult),
max(a.StudentResult),min(a.StudentResult) from result a
LEFT JOIN student b on a.StudentNo=b.StudentNo
where b.StudentName = "武松";