DDL
****
CREATE TABLE `tb_student` ( `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `class_code` int NOT NULL DEFAULT '0' COMMENT '所属班级编号', `user_code` int unsigned NOT NULL DEFAULT '0' COMMENT '学生编号', `user_name` varchar(10) NOT NULL DEFAULT '' COMMENT '学生姓名', `gender` char(1) NOT NULL DEFAULT '男' COMMENT '性别', `birthday` date NOT NULL DEFAULT '1970-01-01' COMMENT '生日', `home_address` varchar(100) NOT NULL DEFAULT '' COMMENT '家庭住址', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_class_user_code` (`class_code`,`user_code`), UNIQUE KEY `uk_user_code` (`user_code`), KEY `idx_class_code` (`class_code`) ) ENGINE=InnoDB AUTO_INCREMENT=1081 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='学生信息表';
我们这里有一个表总共有18个班,一个班60个学生。
SELECT 就是选择的意思,此处一般是结果集中的列,如果有多列就用逗号分隔,查询列表的最后一个字段后没有逗号。(英文符号的逗号)
select * from tb_student;
不推荐上面这种写法,因为可能实际中会有很多数据的冗余,造成IO压力,推荐列出指定的列,如:
select id,class_code,user_code,user_name,gender,birthday,home_address,create_time,update_time from tb_student;
有时我们并不需要那么多的信息,比如只想要学号,或者只要基本的信息
#只查学号列 select user_code from tb_student; #查询学生基本的信息 select class_code,user_code,user_name,gender,birthday,home_address from tb_student;
有时你可能还是看不懂,就给列取个别名mysql里可以直接在列名后面再写一个名字,或者使用AS。
select class_code as '班级编号', user_code as '学号', user_name as '姓名', birthday as '出生年月', home_address as '家庭地址' from tb_student;
+--------------+--------+-----------+--------------+------------------------------------------------------------+ | 班级编号 | 学号 | 姓名 | 出生年月 | 家庭地址 | +--------------+--------+-----------+--------------+------------------------------------------------------------+ | 3001 | 6080 | 陈晓畅 | 2009-03-07 | 盐田区田心东路9号 | | 3001 | 6079 | 康又蓝 | 2009-11-30 | 福田区农林路1号 | | 3001 | 6078 | 蒋芸溪 | 2009-09-07 | 福田区皇岗路莲花一村华富街道办事处综合楼 | | 3001 | 6077 | 王淑慧 | 2009-02-27 | 盐田区东海四街2号盐田街道办事处213室 | | 3001 | 6076 | 朱米琪 | 2009-07-26 | 光明区新湖街道旧围1号 | +--------------+--------+-----------+--------------+------------------------------------------------------------+
我们还可以用在一些特定的函数或者常量的处理
select user(), now(), current_date(), current_time(), current_timestamp();
+----------------+---------------------+----------------+----------------+---------------------+ | user() | now() | current_date() | current_time() | current_timestamp() | +----------------+---------------------+----------------+----------------+---------------------+ | root@localhost | 2022-03-04 06:06:12 | 2022-03-04 | 06:06:12 | 2022-03-04 06:06:12 | +----------------+---------------------+----------------+----------------+---------------------+
有时导出数据,可能需要固定的一列,就可以类似的用法
select user_name as '姓名','学生' as '类型' from tb_student;
+-----------+--------+ | 姓名 | 类型 | +-----------+--------+ | 陈晓畅 | 学生 | | 康又蓝 | 学生 | | 蒋芸溪 | 学生 | +-----------+--------+
FROM 一般就是从哪个表或者结果集进行操作
#从学生表中查询 select user_code,user_name from tb_student;
这种情况的使用场景是,其他表得出一个结果,然后再对结果集进行过滤。
#字段1 和 字段2 必须是 查询语句的查出来的列名 select 字段1,字段2 from (子查询语句) as 结果集的别名;
WHERE 就是一个条件过滤,比如要查询,修改或者删除数据,不加条件就是全表操作了。因为有时我们只是操作我们需要的数据,所以这个 WHERE 就是我们的条件了。
#从学生表中查询学生编号为6080的学生姓名 select user_name from tb_student where user_code=6080;
WHERE 不仅可以用在查询,还可以用在修改或删除的语句中。
#更新学生编号为6080学生的生日为2020-12-12 update tb_student set birthday='2020-12-12' where user_code=6080; #删除学生编号为6080学生 delete from tb_student where user_code=6080;
COUNT 可以用来统计符合条件的记录数。
#使用count(*)查询学生表的学生的总数 select count(*) from tb_student;
或者使用
#使用count(非空列)查询学生表的学生的总数 select count(user_code) from tb_student;
使用count(*),count(列),这两者有区别的,count(*)是统计所有行记录,count(列)一般是非空列的记录,假设有5个学生,有4个学生填了生日,有一个为空,如果这时按照生日这列去统计就结果就是4了,但是如果你按照唯一编号去统计就是5了
数据库有很多记录,有时我们可能只需要指定的几条, LIMIT 就是限制查询结果的行数。
查询 m 条记录
#查询学生表的前5条记录 select user_code, user_name from tb_student limit 5;
+-----------+-----------+ | user_code | user_name | +-----------+-----------+ | 6080 | 陈晓畅 | | 6079 | 康又蓝 | | 6078 | 蒋芸溪 | | 6077 | 王淑慧 | | 6076 | 朱米琪 | +-----------+-----------+
查询 m 条记录,但是索引是从 n 开始(数据库查询结果索引是从0开始)
#查询学生表记录,从1第一条开始(索引是0),查询三条 select user_code, user_name from tb_student limit 1,3;
+------------+-----------+ | class_code | user_name | +------------+-----------+ | 3001 | 康又蓝 | | 3001 | 蒋芸溪 | | 3001 | 王淑慧 | +------------+-----------+
LIKE中的( % )表示的是任意的意思,可以前面任意,后面任意,或者前后都任意(分别如下):
#比如我们查询姓“张”的学生的学号和姓名 select user_code, user_name from tb_student where user_name like '张%';
+-----------+-----------+ | user_code | user_name | +-----------+-----------+ | 6023 | 张雪珍 | | 5690 | 张梦露 | | 5542 | 张悦和 | | 5467 | 张妙意 | | 5404 | 张香岚 | | 5298 | 张娇洁 | | 5255 | 张水蓉 | +-----------+-----------+
#比如我们查询叫“雨文”的学生的学号和姓名 select user_code, user_name from tb_student where user_name like '%雨文';
+-----------+-----------+ | user_code | user_name | +-----------+-----------+ | 6074 | 余雨文 | | 5200 | 刘雨文 | +-----------+-----------+
#比如我们查询名字中含有“雨”的学生的学号和姓名 select user_code, user_name from tb_student where user_name like '%雨%';
+-----------+-----------+ | user_code | user_name | +-----------+-----------+ | 6074 | 余雨文 | | 5942 | 崔昕雨 | | 5850 | 丁小雨 | | 5814 | 丁雨灵 | | 5695 | 曹雨竹 | | 5651 | 钱雨兰 | | 5639 | 田雨旋 | | 5521 | 康雨彤 | | 5478 | 韩新雨 | | 5368 | 陆雨柏 | | 5341 | 苏雨真 | | 5331 | 胡雨琴 | | 5263 | 沈甘雨 | | 5244 | 戴雨双 | | 5216 | 邹雨筠 | | 5200 | 刘雨文 | | 5078 | 赵雨云 | +-----------+-----------+
LIKE中的( _ )表示的是任意一位的意思,只表示一位,和 % 有区别,如果想要表示任意两位就两个下划线。
#比如我们查询名字中第三个字是“雨”的学生的学号和姓名 select user_code, user_name from tb_student where user_name like '__雨';
+-----------+-----------+ | user_code | user_name | +-----------+-----------+ | 5942 | 崔昕雨 | | 5850 | 丁小雨 | | 5478 | 韩新雨 | | 5263 | 沈甘雨 | +-----------+-----------+
#比如我们查询名字中第二个字是“雨”的学生的学号和姓名 select user_code, user_name from tb_student where user_name like '_雨_';
+-----------+-----------+ | user_code | user_name | +-----------+-----------+ | 6074 | 余雨文 | | 5814 | 丁雨灵 | | 5695 | 曹雨竹 | | 5651 | 钱雨兰 | | 5639 | 田雨旋 | | 5521 | 康雨彤 | | 5368 | 陆雨柏 | | 5341 | 苏雨真 | | 5331 | 胡雨琴 | | 5244 | 戴雨双 | | 5216 | 邹雨筠 | | 5200 | 刘雨文 | | 5078 | 赵雨云 | +-----------+-----------+
#家庭地址第四到第六位是"观光路"的学生的学号,姓名和具体地址 SELECT user_code, user_name,home_address FROM tb_student where home_address like '___观光路%';
+------------+-----------+---------------------------+ | class_code | user_name | home_address | +------------+-----------+---------------------------+ | 6075 | 史采枫 | 龙华区观光路1199号 | | 6059 | 周虹颖 | 龙华区观光路1446号 | | 6057 | 卢友桃 | 南山区观光路65号 | | 5979 | 梁宛亦 | 龙岗区观光路 | +------------+-----------+---------------------------+
IN 表示在指定的值中,如果是字符串则用引号,一般的写法是:
in(值1,值2,值3,...,值n)
#查询学号为3007,3008,3015学生的姓名和住址 SELECT user_name,home_address FROM tb_student where user_code in(3007,3008,3015);
+-----------+----------------------------------------------+ | user_name | home_address | +-----------+----------------------------------------------+ | 陈绮烟 | 盐田区大梅沙盐葵路88号 | | 杜晓蕾 | 福田区松岭路56号 | | 余施诗 | 罗湖区东湖路92号东湖街道办事处 | +-----------+----------------------------------------------+
和 IN 差不多,只是前面多个 NOT 一般的写法是:
not in(值1,值2,值3,...,值n)
#查询三班(3001)学号不是3007,3008,3015学生的姓名和住址 SELECT class_code,user_code, user_name FROM tb_student where class_code=3001 and user_code not in(3007,3008,3015);
+------------+-----------+-----------+ | class_code | user_code | user_name | +------------+-----------+-----------+ | 3001 | 6080 | 陈晓畅 | | 3001 | 6079 | 康又蓝 | | 3001 | 6078 | 蒋芸溪 | | 3001 | 6077 | 王淑慧 | | 3001 | 6076 | 朱米琪 | | 3001 | 6075 | 史采枫 | | 3001 | 6074 | 余雨文 | | 3001 | 6073 | 尹滢渟 | | 3001 | 6072 | 谢骊艳 | | 3001 | 6071 | 吴恬美 | | 3001 | 6070 | 唐静珊 | | 3001 | 6069 | 宋芳蕙 | | 3001 | 6068 | 邹蓉城 | | 3001 | 6067 | 萧谷蓝 | | 3001 | 6066 | 罗香之 | | 3001 | 6065 | 崔愉心 | | 3001 | 6064 | 傅燕楠 | | 3001 | 6063 | 高北辰 | | 3001 | 6062 | 郑雪巧 | | 3001 | 6061 | 孔韵诗 | | 3001 | 6060 | 唐涵易 | | 3001 | 6059 | 周虹颖 | | 3001 | 6058 | 杜半雪 | | 3001 | 6057 | 卢友桃 | | 3001 | 6056 | 魏舒兰 | | 3001 | 6055 | 王从霜 | | 3001 | 6054 | 薛秀曼 | | 3001 | 6053 | 徐初阳 | | 3001 | 6052 | 郝灵寒 | | 3001 | 6051 | 郭艳蕙 | | 3001 | 6050 | 潘安春 | | 3001 | 6049 | 罗惜文 | | 3001 | 6048 | 顾初雪 | | 3001 | 6047 | 余天欣 | | 3001 | 6046 | 陆静姝 | | 3001 | 6045 | 姜傲南 | | 3001 | 6044 | 冯代柔 | | 3001 | 6043 | 黄青柏 | | 3001 | 6042 | 薛夏青 | | 3001 | 6041 | 邱畅然 | | 3001 | 6040 | 姜月明 | | 3001 | 6039 | 洪敏叡 | | 3001 | 6038 | 袁璇玑 | | 3001 | 6037 | 郭忆灵 | | 3001 | 6036 | 蔡斯乔 | | 3001 | 6035 | 韦醉柳 | | 3001 | 6034 | 於南莲 | | 3001 | 6033 | 侯姣丽 | | 3001 | 6032 | 石忆秋 | | 3001 | 6031 | 唐欣悦 | | 3001 | 6030 | 侯菱凡 | | 3001 | 6029 | 郭以南 | | 3001 | 6028 | 潘思柔 | | 3001 | 6027 | 孙冰蓝 | | 3001 | 6026 | 沈寄瑶 | | 3001 | 6025 | 袁娟秀 | | 3001 | 6024 | 於晓丝 | | 3001 | 6023 | 张雪珍 | | 3001 | 6022 | 石清妙 | | 3001 | 6021 | 吴娴静 | +------------+-----------+-----------+
之前 IN 或者 NOT IN 都是具体的值,其实还可以指定范围,比如我们说的 BETWEEN AND ,大概语法是
between 开始区间 and 结束区间
#查询在2009-02-17到2009-02-22出生的学生的信息 SELECT user_code, user_name,birthday FROM tb_student where birthday between '2009-02-17' and '2009-02-22';
+-----------+-----------+------------+ | user_code | user_name | birthday | +-----------+-----------+------------+ | 6071 | 吴恬美 | 2009-02-17 | | 6032 | 石忆秋 | 2009-02-17 | | 6013 | 董莺韵 | 2009-02-22 | | 5858 | 刘木兰 | 2009-02-19 | +-----------+-----------+------------+
从结果我们也知道, BETWEEN AND 的结果是 包含开始区间和结束区间的
#按班级统计每班的人数 select class_code,count(*) from tb_student group by class_code;
+------------+----------+ | class_code | count(*) | +------------+----------+ | 3001 | 60 | | 3002 | 60 | | 3003 | 60 | | 3004 | 60 | | 3005 | 60 | | 3006 | 60 | | 3007 | 60 | | 3008 | 60 | | 3009 | 60 | | 3010 | 60 | | 3011 | 60 | | 3012 | 60 | | 3013 | 60 | | 3014 | 60 | | 3015 | 60 | | 3016 | 60 | | 3017 | 60 | | 3018 | 60 | +------------+----------+
需要注意的是,如果你使用 GROUP BY 进行分组,除了分组的字段,其他的字段,你就不能进行选取了。
HAVING 一般和 GROUP BY 使用居多,对分组后的数据进行过滤
#按班级统计每班的人数,并筛选出大于60人的班级 select class_code,count(*) as num from tb_student group by class_code having num > 60;
Empty set (0.00 sec)
ORDER BY 就是排序,可以是升序,或者降序,默认是升序。
#比如按出生日期查询最大的5名学生的姓名和生日 select user_name,birthday from tb_student order by birthday asc limit 5;
+-----------+------------+ | user_name | birthday | +-----------+------------+ | 邓闲华 | 2007-01-06 | | 夏芷雁 | 2007-01-07 | | 崔晓青 | 2007-01-10 | | 汪易松 | 2007-01-10 | | 王绿凝 | 2007-01-11 | +-----------+------------+
#比如按出生日期查询最小的5名学生的姓名和生日 select user_name,birthday from tb_student order by birthday desc limit 3;
+-----------+------------+ | user_name | birthday | +-----------+------------+ | 傅紫文 | 2010-12-23 | | 康子薇 | 2010-12-22 | | 郭飞柏 | 2010-12-21 | | 金丹烟 | 2010-12-19 | | 段贞婉 | 2010-12-19 | +-----------+------------+
#比如按出生日期查询10名学生的姓名、生日和学号,要求按照生日升序,学号降序 select user_name,birthday,user_code from tb_student order by birthday asc, user_code desc limit 10;
+-----------+------------+-----------+ | user_name | birthday | user_code | +-----------+------------+-----------+ | 邓闲华 | 2007-01-06 | 5356 | | 夏芷雁 | 2007-01-07 | 5161 | | 汪易松 | 2007-01-10 | 5106 | | 崔晓青 | 2007-01-10 | 5090 | | 范玉琲 | 2007-01-11 | 5338 | | 王绿凝 | 2007-01-11 | 5247 | | 赵流逸 | 2007-01-11 | 5227 | | 杜觅双 | 2007-01-14 | 5317 | | 雷慧月 | 2007-01-16 | 5279 | | 谭代曼 | 2007-01-18 | 5184 | +-----------+------------+-----------+
可以看到生日是升序的,生日相同的情况下,学号是降序的。
#查询学号为5781和5546的学生的姓名 select user_name from tb_student where user_code in(5781,5546);
+-----------+ | user_name | +-----------+ | 夏晶晶 | | 夏晶晶 | +-----------+
#查询学号为5781和5546的学生的姓名 select distinct user_name from tb_student where user_code in(5781,5546);
+-----------+ | user_name | +-----------+ | 夏晶晶 | +-----------+
需要注意的是,如果你选择的是多列,比如你是
select distinct user_name,user_code from tb_student where user_code in(5781,5546);
那么它就是按照user_name+user_code 这个组合是否重复来处理的
±----------±----------+
| user_name | user_code |
±----------±----------+
| 夏晶晶 | 5546 |
| 夏晶晶 | 5781 |
±----------±----------+