"""
1.> as 起别名
1.>给字段起别名:select id as '学号',name as '芳名'from students;
2.>给表起别名:select s.id,s.name from students as s;
注意:as可以不写,省略.
select s.id,s.name from students s;
2.>去重:distinct
select distinct gender from students;
多个字段:
select distinct age,gender from students;
满足age和gender都一样的记录才会被去除,只有age或者gender一样的不会被去掉.
3.> where 筛选:
从表<集合>筛选出满足条件的记录<记录就是行数据>
select * from students where age=18;
select * from students where age>18;
select * from students where age<18;
select * from students where age>=18;
select * from students where age<=18;
# != 等价于 <>
select * from students where age!=18;
select * from students where age<>18;
18到30岁的
select * from students where age between 18 and 30;
select * from students where age>18 and age<30;
或者:or
select * from students where age>18 or gender=1;
取反 not: age不大于18的
select * from students where not age>18;
# 这种是错误的,mysql中没有这种形式
select * from students where 18<age<30;
4.>enum():枚举本质是数字,从1开始
enum('男','女','中性','保密') 对应关系是 1-->男,2-->女,3-->中性,4-->保密
utf8中%这种可以匹配多个字节
5.>like模糊查询:
% --> 匹配任意个任意字符 类似于正则的*
_ --> 匹配一个任意字符 类似于正则的?
# 表示name中以王开头的,王x或者王xxxxxxx,均可
select * from students where name like '王%';
# 表示name中以王开头的,只能是王x这种格式的
select * from students where name like '王_';
#一般常用:表示查询表中指定字段name中含有指定字符王的记录
select * from students where name like '%王%';
# 不含有王的
select * from students where name not like '%王%';
6.>范围查询:
age=18或者age=28或者age=38
select * from where age in (18,28,38);
age!=18或者age!=28或者age!=38
select * from where age not in (18,28,38);
between...and...:表示连续范围
select * from where age between 18 and 45;闭区间,可以取到上下限
# 不在这个范围内
select * from where age not between 18 and 45;
7.>判断是否为空: is null
NULL是一种状态,不是具体的数据,所以不可以使用=NULL去判断
只能使用is NULL表示,意为是否为空
# 是空 不区分大小写 所以null和NULL均可以.
select * from students where height is null;
# 是非空 is not NULL 而不是not is NULL
select * from students where height is not NULL;
8.>排序: order by 字段名; 默认是升序 asc-->ascend:上升
降序使用desc<PS注意和描述表结构里面的desc 表名 区分> ---> descend:下降
asc:默认升序,可以不写
select * from students order by age desc;
# 组合使用:建议多个条件时候的and往前写
select * from students where gender=1 and age between 18 and 58 order by age;
# order by后面可以跟上多个字段. 先按身高height降序排,相同身高的按年龄age升序排
select * from students where gender=2 and age between 18 and 58 order by height desc,age asc;
9.> 分页:搜索结果部分显示 按照用户的条件
limit 0,9 ---> 0表示数据的起始下标,9表示一页显示的数据的数量
limit 数量 * (页面-1),数量
一般和排序合在一起使用:就是将结果部分显示
select * from students order by height desc limit 3;
select * from students order by height desc limit 0,3;
# 把最高的去掉之后的最高
select * from students order by height desc limit 1,3;
limit分页的数据是可以不排序的,需要排序得加order by
如果是日常生活说第一个,那就是1开始的,但是数据检索的时候第一条数据是0开始计数的.注意区分.
# 身高第四到第八:
select * from students order by height desc limit 3,5;
#限制查询出来的数据是2条
select * from students where gender=1 limit 2;
# 查询前5个数据
select * from students limit 5
# 每页显示2个,第一个页面是0,1
select * from students limit 0,2;
第2个页面是0,1
select * from students limit 2,2;
3个页面是2,3
select * from students limit 4,2;
4个页面是4,5
select * from students limit 6,2;
#主要是电商网站分页显示
n个页面:每个页面显示m条数据
select * from students limit m*(n-1),m;
# 每页2条,显示第6页的,
select * from students order by age limit 10,2;
"""
# --------------------------------聚合函数------------------------->
"""
sum/min/count/max/avg 就是把多个数据合成一个数据
组函数:对一组数据进行统计
特点:忽略字段为NULL的记录
不允许出现嵌套 count(sum(height)) 因为sum()返回的是一个数据,不是一组数据,所以绝对不能嵌套.
1.>count(*):统计,有多少,总数 *表示任意,
select count(height) from students; height字段中不为空的
select count(*) from students; 所有的,包括空的
对性别统计总数
select count(distinct gender) from students;
2.>max():最大
select max(height),max(age) from students;
3.>min():最小
select min(height) from students where gender=1;
4.sum():求和
select sum(height)/count(height) from students where gender=2;
select avg(height) from students where gender=2;
5.>round():四舍五入
round(参数1,参数2)不是组函数,参数1是一个数字,参数2是一个整数,表示保留的小数位数.
select round(122.34567890,5);
+-----------------------+
| round(122.34567890,5) |
+-----------------------+
| 122.34568 |
+-----------------------+
select round(avg(age)) from students; 输出28,不写就是整数
select round(avg(age),2) from students; 输出 27.64 保留2位小数
# 男性平均年龄
select round(avg(age),2) as '男性平均年龄' from students where gender=1;
输出:
+--------------------+
| 男性平均年龄 |
+--------------------+
| 32.60 |
+--------------------+
ps:浮点数<即小数>在数据库中不是精确存储的,不要进行精确匹配=,只能进行大于小于等
"""
# ---------------------------------分组:group by ----------------------->
"""
聚合函数:
默认情况下没有分组的情况 是对整个表进行统计计算
但是,如果分组了,就是对分组后的每个组进行统计计算.
"""
"""
1.>group by:
SQL语句只能对二维的数据表进行操作.
select * from students group by gender;这样是错误的
select gender from students group by gender;只能查看我们进行分组group by 后面的字段
+--------+
| gender |
+--------+
| 男 |
| 女 |
| 中性 |
| 保密 |
+--------+
计算每种性别及对应的人数
select count(*)from students group by gender;
+----------+
| count(*) |
+----------+
| 5 |
| 7 |
| 1 |
| 1 |
+----------+
注意:一旦分组和聚合函数合用,聚合函数不再统计整体结果,而是统计每个小组的结果
查找性别及对应的每个性别的平均年龄:
select gender,avg(age)from students group by gender;
+--------+----------+
| gender | avg(age) |
+--------+----------+
| 男 | 32.6000 |
| 女 | 23.2857 |
| 中性 | 33.0000 |
| 保密 | 28.0000 |
+--------+----------+
扩展:select 后面的字段,要么是group by分组后面的字段,要么是放在聚合函数中的,其余情况都会出错
显示具体的分组中每个成员的某个字段的数据,并且拼接显示在一起--->group_concat()
select gender,avg(age),group_concat(age) from students group by gender;
+--------+----------+----------------------+
| gender | avg(age) | group_concat(age) |
+--------+----------+----------------------+
| 男 | 32.6000 | 29,59,36,27,12 |
| 女 | 23.2857 | 18,18,38,18,25,12,34 |
| 中性 | 33.0000 | 33 |
| 保密 | 28.0000 | 28 |
+--------+----------+----------------------+
注意: 起别名的as 可以不写,直接在字段名后面跟 新名字,不要加,号
select group_concat(name) '姓名',group_concat(age) '年龄',gender,avg(age) '平均年龄
' from students group by gender;
+------------------------------------------+----------------------+--------+----------+
| 姓名 | 年龄 | gender | 平均年龄 |
+------------------------------------------+----------------------+--------+----------+
| 彭于晏,刘德华,周杰伦,程坤,郭靖 | 29,59,36,27,12 | 男 | 32.6 |
| 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰 | 18,18,38,18,25,12,34 | 女 | 23.2857 |
| 金星 | 33 | 中性 | 33 |
| 凤姐 | 28 | 保密 | 28 |
+------------------------------------------+----------------------+--------+----------+
select gender,name from students group by gender; --->这样是错误的
select gender,group_concat(name) from students group by gender;
+--------+-----------------------------------------------------------+
| gender | group_concat(name) |
+--------+-----------------------------------------------------------+
| 男 | 彭于晏,刘德华,周杰伦,程坤,郭靖 |
| 女 | 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰 |
| 中性 | 金星 |
| 保密 | 凤姐 |
+--------+-----------------------------------------------------------+
select gender,group_concat(name),count(*) from students group by gender;
+--------+-----------------------------------------------------------+----------+
| gender | group_concat(name) | count(*) |
+--------+-----------------------------------------------------------+----------+
| 男 | 彭于晏,刘德华,周杰伦,程坤,郭靖 | 5 |
| 女 | 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰 | 7 |
| 中性 | 金星 | 1 |
| 保密 | 凤姐 | 1 |
+--------+-----------------------------------------------------------+----------+
2.>having: 对分组加条件进行筛选.和where不同,where是对表数据筛选
select gender,group_concat(name),count(*) from students group by gender having count(*)>2;
+--------+-----------------------------------------------------------+----------+
| gender | group_concat(name) | count(*) |
+--------+-----------------------------------------------------------+----------+
| 男 | 彭于晏,刘德华,周杰伦,程坤,郭靖 | 5 |
| 女 | 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰 | 7 |
+--------+-----------------------------------------------------------+----------+
select gender,group_concat(name) from students group by gender having avg(age) <= 30;
select gender,group_concat(name) from students group by gender having avg(age) <= 30;
+--------+-----------------------------------------------------------+
| gender | group_concat(name) |
+--------+-----------------------------------------------------------+
| 女 | 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰 |
| 保密 | 凤姐 |
+--------+-----------------------------------------------------------+
select gender,group_concat(name) from students group by gender having count(*) <= 5;
+--------+-----------------------------------------------------------+
| gender | group_concat(name) |
+--------+-----------------------------------------------------------+
| 男 | 彭于晏,刘德华,周杰伦,程坤,郭靖 |
| 女 | 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰 |
| 中性 | 金星 |
| 保密 | 凤姐 |
+--------+-----------------------------------------------------------+
汇总显示:with rollup
select gender,group_concat(name) from students group by gender with rollup; +--------+---------------------------------------------------------------------------------------------------------------------+
| gender | group_concat(name) |
+--------+---------------------------------------------------------------------------------------------------------------------+
| 男 | 彭于晏,刘德华,周杰伦,程坤,郭靖 |
| 女 | 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰 |
| 中性 | 金星 |
| 保密 | 凤姐 |
| NULL | 彭于晏,刘德华,周杰伦,程坤,郭靖,小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰,金星,凤姐 |
+--------+---------------------------------------------------------------------------------------------------------------------+
"""
# -------------------------------连接-------------------------------->
"""
应用场景:当需要把多张表的数据汇总在一张表里面显示的时候,需要使用连接.
A:A是左表 B:B是右表
1.>内连接:A B两个表有关联的地方显示在一张表中显示
外连接是建立在内连接的基础上.
2.>右连接:<外连接> 内连接+ 额外数据如果来自右表,称之为右连接
3.>左连接:<外连接> 内连接+ 额外数据如果来自左表,称之为左连接
内连接:求两个表关联的数据
外连接:在内连接的基础上 添加外部数据,来自左边,左外来自右边,右外.
笛卡尔积:左表和右表中的每一条记录分别进行拼接组合.
关联:不一定是相等,可以大于,小于,或者大于等于等等
select * from hero join gongfu;
就把hero join gongfu当做一张表就好.是hero和gongfu两张表合并之后的新表
join或者cross join
需要的数据就在笛卡尔积里面出现了.如何把这些需要的数据筛选出来才是王道
+----+-----------+----------+----+--------------+
| id | name | kongfuid | id | kongfu |
+----+-----------+----------+----+--------------+
| 1 | 妲己 | 2 | 1 | 吟诗作对 |
| 2 | 李白 | 1 | 1 | 吟诗作对 |
| 3 | 程咬金 | 3 | 1 | 吟诗作对 |
| 4 | 共孙俪 | 5 | 1 | 吟诗作对 |
| 1 | 妲己 | 2 | 2 | 推心置腹 |
| 2 | 李白 | 1 | 2 | 推心置腹 |
| 3 | 程咬金 | 3 | 2 | 推心置腹 |
| 4 | 共孙俪 | 5 | 2 | 推心置腹 |
| 1 | 妲己 | 2 | 3 | 半路杀出 |
| 2 | 李白 | 1 | 3 | 半路杀出 |
| 3 | 程咬金 | 3 | 3 | 半路杀出 |
| 4 | 共孙俪 | 5 | 3 | 半路杀出 |
| 1 | 妲己 | 2 | 4 | 沉默是金 |
| 2 | 李白 | 1 | 4 | 沉默是金 |
| 3 | 程咬金 | 3 | 4 | 沉默是金 |
| 4 | 共孙俪 | 5 | 4 | 沉默是金 |
+----+-----------+----------+----+--------------+
表和表之间关联的字段,这里是kongfuid和kongfu表中id一致
on:后面加上条件判断
inner 可以省略
select * from hero inner join gongfu on hero.kongfuid=gongfu.id;
select * from hero join gongfu on hero.kongfuid=gongfu.id;
+----+-----------+----------+----+--------------+
| id | name | kongfuid | id | kongfu |
+----+-----------+----------+----+--------------+
| 2 | 李白 | 1 | 1 | 吟诗作对 |
| 1 | 妲己 | 2 | 2 | 推心置腹 |
| 3 | 程咬金 | 3 | 3 | 半路杀出 |
+----+-----------+----------+----+--------------+
左外连接:outer 可以省略不写,多个左表的数据
select * from hero left outer join gongfu on hero.kongfuid=gongfu.id;
select * from hero left join gongfu on hero.kongfuid=gongfu.id;
+----+-----------+----------+------+--------------+
| id | name | kongfuid | id | kongfu |
+----+-----------+----------+------+--------------+
| 2 | 李白 | 1 | 1 | 吟诗作对 |
| 1 | 妲己 | 2 | 2 | 推心置腹 |
| 3 | 程咬金 | 3 | 3 | 半路杀出 |
| 4 | 共孙俪 | 5 | NULL | NULL |
+----+-----------+----------+------+--------------+
右外连接: outer 可以省略不写,多个右表的数据
select * from hero right outer join gongfu on hero.kongfuid=gongfu.id;
select * from hero right join gongfu on hero.kongfuid=gongfu.id;
+------+-----------+----------+----+--------------+
| id | name | kongfuid | id | kongfu |
+------+-----------+----------+----+--------------+
| 1 | 妲己 | 2 | 2 | 推心置腹 |
| 2 | 李白 | 1 | 1 | 吟诗作对 |
| 3 | 程咬金 | 3 | 3 | 半路杀出 |
| NULL | NULL | NULL | 4 | 沉默是金 |
+------+-----------+----------+----+--------------+
注意:cross join 使用的时候就不能再加left或者right 还有outer这些关键字了
select * from hero cross join gongfu on hero.kongfuid=gongfu.id;
+----+-----------+----------+----+--------------+
| id | name | kongfuid | id | kongfu |
+----+-----------+----------+----+--------------+
| 2 | 李白 | 1 | 1 | 吟诗作对 |
| 1 | 妲己 | 2 | 2 | 推心置腹 |
| 3 | 程咬金 | 3 | 3 | 半路杀出 |
+----+-----------+----------+----+--------------+
# 自连接: 一种特殊的连接,连接需要对左表和右表分别起别名<左表和右表是同一个表>
注意:必须起别名,as可以省略.
1.>汇总的数据来自一张表的时候.
步骤:
1.>areas.sql文件拷贝到linux桌面
2.>进入桌面:cd ~/Desktop
3.>登录mysql
4.>选择数据库 use py_test
5.>创建表
create table areas(
aid int primary key,
atitle varchar(20),
pid int
);
6.>在 mysql命令终端下面执行 source F:/areas.sql 这样就把数据导入到库中了.
形式: select * from 表 as 别名1 join 表 as 别名2 on 别名1.字段= 别名2.字段;
查询笛卡尔积的记录数量:
select count(*) from areas pro join areas city;
# 查询深圳市下属所有区
select * from areas pro join areas city on city.pid = pro.aid where pro.atitle='深圳市';
+--------+-----------+--------+--------+-----------+--------+
| aid | atitle | pid | aid | atitle | pid |
+--------+-----------+--------+--------+-----------+--------+
| 440300 | 深圳市 | 440000 | 440303 | 罗湖区 | 440300 |
| 440300 | 深圳市 | 440000 | 440304 | 福田区 | 440300 |
| 440300 | 深圳市 | 440000 | 440305 | 南山区 | 440300 |
| 440300 | 深圳市 | 440000 | 440306 | 宝安区 | 440300 |
| 440300 | 深圳市 | 440000 | 440307 | 龙岗区 | 440300 |
| 440300 | 深圳市 | 440000 | 440308 | 盐田区 | 440300 |
+--------+-----------+--------+--------+-----------+--------+
子查询:select的嵌套
select 里面嵌入另外一个select查询
分类:
标量子查询:子查询的结果是一个数据<一行或一列> 返回的查询结果是一个数,一个值
行子查询:返回的结果是一行
列子查询:返回的结果是一列
表子查询:返回的结果是一个表
标量子查询:最高身高的姓名
select name from students where height = (select max(height) from students);
+-----------+
| name |
+-----------+
| 彭于晏 |
+-----------+
高于平均身高的. 也是一个标量子查询
mysql> select name from students where height >= (select avg(height) from students);
+-----------+
| name |
+-----------+
| 小明 |
| 小月月 |
| 彭于晏 |
| 刘德华 |
| 程坤 |
| 静香 |
| 周杰 |
+-----------+
行子查询:返回的结果是一行. 求身高最高并且年龄最大的. 注意:这里拿元组类型来接收(height,age)=(185.00,59)
select * from students where (height,age) = (select max(height),max(age) from students);
+----+-----------+------+--------+--------+--------+-----------+
| id | name | age | height | gender | cls_id | is_delete |
+----+-----------+------+--------+--------+--------+-----------+
| 4 | 刘德华 | 59 | 185.00 | 男 | 2 | |
+----+-----------+------+--------+--------+--------+-----------+
列子查询:返回的结果是一列 找出已经开班班级的所有学生信息
select id from classes---> 返回的结果是一列
select * from students where cls_id in (select id from classes);
+----+-----------+------+--------+--------+--------+-----------+
| id | name | age | height | gender | cls_id | is_delete |
+----+-----------+------+--------+--------+--------+-----------+
| 1 | 小明 | 18 | 180.00 | 女 | 1 | |
| 2 | 小月月 | 18 | 180.00 | 女 | 2 | |
| 3 | 彭于晏 | 29 | 185.00 | 男 | 1 | |
| 4 | 刘德华 | 59 | 185.00 | 男 | 2 | |
| 5 | 黄蓉 | 38 | 160.00 | 女 | 1 | |
| 6 | 凤姐 | 28 | 150.00 | 保密 | 2 | |
| 7 | 王祖贤 | 18 | 172.00 | 女 | 1 | |
| 8 | 周杰伦 | 36 | NULL | 男 | 1 | |
| 9 | 程坤 | 27 | 181.00 | 男 | 2 | |
| 10 | 刘亦菲 | 25 | 166.00 | 女 | 2 | |
+----+-----------+------+--------+--------+--------+-----------+
总结:等下回去看
关键字顺序:
select * from 表名
[join 表名]
[on 连接条件]
[where 条件判断]
[group by 字段名] [asc|desc],...字段名 [asc|desc]...
[having 条件判断]
[order by 字段名 ][asc|desc]
[limit 起始位置,每一页显示的数据个数]
"""
"""
SQL 语句的完整格式:
SELECT select_expr [,select_expr,...] [
FROM tb_name
[JOIN 表名]
[ON 连接条件]
[WHERE 条件判断]
[GROUP BY {col_name | postion} [ASC | DESC], ...]
[HAVING 条件判断]
[ORDER BY {col_name|expr|postion} [ASC | DESC], ...]
[ LIMIT {[offset,]rowcount | row_count OFFSET offset}]
]
示例:
select price, group_concat(name) from goods group by price desc;
+-----------+---------------------------------------+
| price | group_concat(name) |
+-----------+---------------------------------------+
| 28888.000 | mac pro专业级台式电脑 |
| 9188.000 | imac me086ch/a 21.5英寸一体电脑 |
| 8499.000 | g150th 15.6英寸游戏本 |
| 7999.000 | svp13226scb 触控超极本 |
| 6999.000 | hmz-t3w 头戴显示设备 |
| 6888.000 | x3250 m4机架式服务器 |
| 5388.000 | poweredge ii服务器 |
| 4999.000 | y400n 14.0英寸笔记本电脑 |
| 4880.000 | x240 超极本 |
| 4299.000 | u330p 13.3英寸超极本 |
| 4288.000 | z220sff f4f06pa工作站 |
| 3699.000 | at7-7414lp 台式电脑 linux ) |
| 3499.000 | ideacentre c340 20英寸一体电脑 |
| 3399.000 | r510vc 15.6英寸笔记本 |
| 3388.000 | ipad air 9.7英寸平板电脑 |
| 2899.000 | vostro 3800-r1206 台式电脑 |
| 2799.000 | x550cc 15.6英寸笔记本 |
| 2788.000 | ipad mini 配备 retina 显示屏 |
| 1998.000 | ipad mini 7.9英寸平板电脑 |
| 99.000 | 商务双肩背包,商务双肩背包 |
+-----------+---------------------------------------+
PS:注意:mysql中没有top关键字命令,top是oracle的. 类似top的功能是limit命令
示例:取出倒数10个:
select * from 表名 order by 字段名 desc limit 10;
"""
# -----------------------navicat 常用快捷键----------------------------->
"""
Navicat常用快捷键
1,Ctrl+q就会弹出一个sql输入窗口
2,Ctrl+r就执行sql了
3,按F6会弹出一个命令窗口 ----> 这样就是类似在mysql的shell界面下进行操作了.
4,Ctrl+/ 注释
5,Ctrl +Shift+/ 解除注释
6,Ctrl+R 运行选中的SQL语句
7,Ctrl+Shift+R 只运行选中的sql语句
8,Ctrl+L 删除选中行内容
9,Ctrl+D 表的数据显示显示页面切换到表的结构设计页面,但是在查询页面写sql时是复制当前行并粘贴到下一行
10,Ctrl+N 打开一个新的查询窗口
11,Ctrl+W 关闭当前查询窗口
12,鼠标三击选择当前行
"""