数据库高级操作

"""
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 * fromas 别名1 joinas 别名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,鼠标三击选择当前行

"""
posted @ 2019-12-26 09:59  砚台是黑的  阅读(193)  评论(0编辑  收藏  举报