zoukankan      html  css  js  c++  java
  • SQL查询语句的进阶使用

    MySQL的进阶使用

    sql语句一些功能的使用

    1. 导入现有大量数据文件步骤
      1) 把*.sql文件拷贝到Linux某一位置(例如Desktop)
      2) Linux命令行进入该位置 cd ~/Desktop
      3) 登录mysql
      4) 使用数据库 mysql> use 数据库名;
      5) 创建表 mysql> 
      	create table 表名(
      	添加字段
      	-- 字段属性要和要导入的文件内数据结构相同
      	);
      6) 执行命令 mysql> source 表名.sql
      
    1. AS 关键字的使用

      - 字段起名
      select id as 序号, name as 名字, gender as 性别 from students;
      
      - 表起名
      select s.id,s.name,s.gender from students as s;
      
    2. 将查询的数据直接插入表中

      insert into xxx (字段名) select 语句
        将select语句的结果集插入到一个表中
      
    3. distinct关键字

      消除重复的行。
      select distinct gender from students;
      

    关于三范式和E-R模型

    1. 三范式

      • 范式指的就是设计数据库的通用规范, 共有8种范式,一般需要遵守3范式即可 1NF强调字段是最小单元,不可再分
      • 2NF强调在1NF基础上必须要有主键和非主键字段必须完全依赖于主键,也就是说 不能部分依赖
      • 3MF强调在2NF基础上 非主键字段必须直接依赖于主键,也就是说不能传递依赖(间接依赖)。
    2. E-R模型 即E-R图

      E-R图由 实体、属性、实体之间的联系构成,主要用来描述 数据库中表结构。 

      • 实体型(Entity):一般对应的是数据中的表名,在E-R图中用矩形表示,矩形框内写明实体名;比如 电商购物系统中用户、购物车、订单等都是实体。
      • 属性(Attribute):一般对应的 表中的字段名称,在E-R图中用椭圆形表示,并用无向边将其与相应的实体连接起来;比如用户的ID、用户名、密码、昵称、身份证号码 都是属性。
      • 联系(Relationship): 实体彼此之间相互连接的方式称为联系,也称为关系。联系可分为以下 3 种类型:
        • 一对一
        • 一对多
        • 多对多
    • 举例一学生表

      mysql> select * from students;
      +----+-----------+------+--------+--------+--------+-----------+
      | 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 | 175.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 |           |
      | 11 | 金星      |   33 | 162.00 | 中性   |      3 |          |
      | 12 | 静香      |   12 | 180.00 | 女     |      4 |           |
      | 13 | 郭靖      |   12 | 170.00 | 男     |      4 |           |
      | 14 | 周杰      |   34 | 176.00 | 女     |      5 |           |
      +----+-----------+------+--------+--------+--------+-----------+
      14 rows in set (0.00 sec)
      

    一、Where 条件

    1. 比较运算符

      等于: =
      大于: >
      大于等于: >=
      小于: <
      小于等于: <=
      不等于: != 或 <>    
      
    2. 逻辑运算符

      and
          查询students表中,年龄在18到28之间的所有学生信息
          错误实例: select * from students where 18<age<28;
          正确: mysql> select * from students where age >= 18 and age <= 28;
      or
      not
      

      and比or先运算,如果同时出现并希望先算or,需要结合()使用

    3. 模糊查询

      like

      ```
       %表示任意多个任意字符
       select * from students where name like '静香%';
       ```

      _表示一个任意字符

      ```
       select * from students where name like '静_';
       ```
    4. 范围查询

      查询编号是1或3或8的学生

      select * from students where id in(1,3,8);
      

      查询编号为3至8的学生

      select * from students where id between 3 and 8;
      

      between A and B在匹配数据的时候匹配的范围空间是 [A,B]

    5. 空判断

      判断为空

      is null
      

      判非空

      is not null
      

    二、排序

    1. 排序查询语法

      select * from 表名 order by 列1 asc|desc [,列2 asc|desc,...]
      

    语法说明:
    1. 将行数据按照列1进行排序,如果某些行 列1 的值相同时,则按照 列2 排序,以此类推
    2. asc从小到大排列,即升序
    3. desc从大到小排序,即降序
    4. 默认按照列值从小到大排列(即asc关键字)

    • 例1:查询未删除男生信息,按学号降序

      select * from students where gender=1 and is_delete=0 order by id desc;
      
    • 例2:查询未删除学生信息,按名称升序

      select * from students where is_delete=0 order by name;
      
    • 例3:显示所有的学生信息,先按照年龄从大-->小排序,当年龄相同时 按照身高从高-->矮排序

      select * from students order by age desc,height desc;
      

    三、分页

    1. 分页查询语法

      select * from 表名 limit start=0,count
          说明
          1. 从start开始,获取count条数据
          2. start默认值为0
          3. 也就是当用户需要获取数据的前n条的时候可以直接写上 xxx limit n;
      

      例:查询前3行男生信息

      select * from students where gender=1 limit 0,3;
      
    2. 获取第n页数据SQL语句的推导公式

      select * from students where is_delete=0 limit (n-1)*m,m
      # 注意:在sql语句中limit后不可以直接加公式
      

    四、聚合函数

    1. count( * ) 表示计算总行数,括号中写星与列名,结果是相同的

      例:查询学生总数

      select count(*) from students;
      
    2. max(列) 表示求此列的最大值

      例:查询女生的编号最大值

      select max(id) from students where gender=2;
      
    3. min(列) 表示求此列的最小值

      例:查询未删除的学生最小编号

      select min(id) from students where is_delete=0;
      
    4. sum(列) 表示求此列的和

      例:查询男生的总年龄

      select sum(age) from students where gender=1;
      -- 平均年龄
      select sum(age)/count(*) from students where gender=1;
      
    5. avg(列) 表示求此列的平均值

      例:查询未删除女生的编号平均值

      select avg(id) from students where is_delete=0 and gender=2;
      

    五、分组

    select * from students;
    +----+-----------+------+--------+--------+--------+-----------+
    | 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 | 175.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 |           |
    | 11 | 金星      |   33 | 162.00 | 中性   |      3 |          |
    | 12 | 静香      |   12 | 180.00 | 女     |      4 |           |
    | 13 | 周杰      |   34 | 176.00 | 女     |      5 |           |
    | 14 | 郭靖      |   12 | 170.00 | 男     |      4 |           |
    +----+-----------+------+--------+--------+--------+-----------+
    

    1. group by分组

    使用特点:

    • group by的含义:将查询结果按照1个或多个字段进行分组,字段值相同的为一组

    • group by可用于单个字段分组,也可用于多个字段分组

      select gender from students group by gender;
      +--------+
      | gender |
      +--------+
      | 男     |
      | 女     |
      | 中性   |
      | 保密   |
      +--------+
      

    2. group_concat(字段名)

    使用特点

    • 根据分组结果,使用group_concat()来放置每一个分组中某字段的集合

      select gender from students group by gender;
      +--------+
      | gender |
      +--------+
      | 男     |
      | 女     |
      | 中性   |
      | 保密   |
      +--------+
      
      select gender,group_concat(name) from students group by gender;
      +--------+-----------------------------------------------------------+
      | gender | group_concat(name)                                        |
      +--------+-----------------------------------------------------------+
      | 男     | 彭于晏,刘德华,周杰伦,程坤,郭靖                                 |
      | 女     | 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰                        |
      | 中性   | 金星                                                       |
      | 保密   | 凤姐                                                       |
      +--------+-----------------------------------------------------------+
      
      
      select gender,group_concat(id) from students group by gender;
      +--------+------------------+
      | gender | group_concat(id) |
      +--------+------------------+
      | 男     | 3,4,8,9,14       |
      | 女     | 1,2,5,7,10,12,13 |
      | 中性   | 11               |
      | 保密   | 6                |
      +--------+------------------+
      

    3. group by + 聚合函数

    使用特点

    • 聚合函数在和group by结合使用的时候 统计的对象是每一个分组。

      select gender,group_concat(age) from students group by gender;
      +--------+----------------------+
      | gender | group_concat(age)    |
      +--------+----------------------+
      | 男     | 29,59,36,27,12       |
      | 女     | 18,18,38,18,25,12,34 |
      | 中性   | 33                   |
      | 保密   | 28                   |
      +--------+----------------------+
      
      
      分别统计性别为男/女的人年龄平均值
      select gender,avg(age) from students group by gender;
      +--------+----------+
      | gender | avg(age) |
      +--------+----------+
      | 男     |  32.6000 |
      | 女     |  23.2857 |
      | 中性   |  33.0000 |
      | 保密   |  28.0000 |
      +--------+----------+
      
      分别统计性别为男/女的人的个数
      select gender,count(*) from students group by gender;
      +--------+----------+
      | gender | count(*) |
      +--------+----------+
      | 男     |        5 |
      | 女     |        7 |
      | 中性   |        1 |
      | 保密   |        1 |
      +--------+----------+
      

    4. group by + having

    • having作用和where类似,但having只能用于group by 而where是用来过滤表数据

      select gender,count(*) from students group by gender having count(*)>2;
      +--------+----------+
      | gender | count(*) |
      +--------+----------+
      | 男     |        5 |
      | 女     |        7 |
      +--------+----------+
      

    5. group by + with rollup

    • with rollup的作用是:在最后新增一行,来记录当前表中该字段对应的操作结果,一般是汇总结果。

      select gender,count(*) from students group by gender with rollup;
      +--------+----------+
      | gender | count(*) |
      +--------+----------+
      | 男     |        5 
      | 女     |        7 |
      | 中性   |        1 |
      | 保密   |        1 |
      | NULL   |       14 |
      +--------+----------+
      
      
      select gender,group_concat(age) from students group by gender with rollup;
      +--------+-------------------------------------------+
      | gender | group_concat(age)                         |
      +--------+-------------------------------------------+
      | 男     | 29,59,36,27,12                            |
      | 女     | 18,18,38,18,25,12,34                      |
      | 中性   | 33                                        |
      | 保密   | 28                                        |
      | NULL   | 29,59,36,27,12,18,18,38,18,25,12,34,33,28 |
      +--------+-------------------------------------------+
      

    六、连接

    1. 连接的概念

      mysql支持三种类型的连接查询,分别为:

      1). 内连接查询:查询的结果为两个表匹配到的数据

      2). 右(外)连接查询:查询的结果为两个表匹配到的数据和右表特有的数据,对于左表中不存在的数据使用null填充

      3). 左(外)连接查询:查询的结果为两个表匹配到的数据和左表特有的数据,对于右表中不存在的数据使用null填充

      注意: 能够使用连接的前提是 多表之间有字段上的关联

    2. 连接查询语法

      # 对于外连接 outer关键字可以省略 
      select * from 表1 inner或left或right join 表2 on 表1.列 运算符 表2.列
      
      例1:使用内连接查询班级表与学生表
      
      select * from students inner join classes on students.cls_id = classes.id;
      例2:使用左连接查询班级表与学生表
      
      # 此处使用了as为表起别名,目的是编写简单
      select * from students as s left join classes as c on s.cls_id = c.id;
      例3:使用右连接查询班级表与学生表
      
      select * from students as s right join classes as c on s.cls_id = c.id;
      例4:查询学生姓名及班级名称
      
      select s.name,c.name from students as s inner join classes as c on s.cls_id = c.id;
      

    七、自连接

    • 当需要将多张"表"的相关数据汇总一个结果集中, 并且多张"表"的数据来自于同一张表
    • 自连接就是一种特殊的连接方式
    • 需要对表起多个不同的别名才能进行自连接查询
    • 注意: 自连接可以使用交叉连接,内连接,外连接多种方式连接

    八、子查询

    1. 子查询的概念

      在一个 select 语句中,嵌入了另外一个 select 语句, 那么被嵌入的 select 语句称之为子查询语句,外部那个select语句则称为主查询.

    2. 主查询和子查询的关系

      • 子查询是嵌入到主查询中
      • 子查询是辅助主查询的,要么充当条件,要么充当数据源
      • 子查询是可以独立存在的语句,是一条完整的 select 语句
    3. 查询的分类

    • 标量子查询:

      • 子查询返回的结果是一个数据(一行一列)
      • 子查询返回的值是max,min,avg等聚合函数得到的值作为一个数据
      • 因为标量子查询只返回一个值,也可以使用其他运算符和标量子查询进行比较,如">, >=, <, <="等
      # 例:查询班级学生的平均身高
      select * from students where age > (select avg(age) from students);
      # 其中第二个select语句就是一个标量子查询
      
    • 列子查询: 返回的结果是一列(一列多行)

      格式:主查询 where 条件 in (列子查询)
      例: 查询还有学生在班的所有班级名字
      1. 找出学生表中所有的班级 id
      2. 找出班级表中对应的名字
      select name from classes where id in (select cls_id from students);
      
    • 行子查询: 返回的结果是一行(一行多列)

      格式: 主查询 where (字段1,2,...) = (行子查询)
      例: 查找班级年龄最大,身高最高的学生
      行元素: 将多个字段合成一个行元素,在行级子查询中会使用到行元素
      select * from students where (height,age) = (select max(height),max(age) from students);
      

    九、完整的sql语句

    SELECT select_expr [,select_expr,...] [      
          FROM tb_name
          [JOIN 表名]
          [ON 连接条件] 
          [WHERE 条件判断]
          [GROUP BY {col_name | postion} [ASC | DESC], ...] 
          [HAVING WHERE 条件判断]
          [ORDER BY {col_name|expr|postion} [ASC | DESC], ...]
          [ LIMIT {[offset,]rowcount | row_count OFFSET offset}]
    ]
    

    十、外键

    • 外键说明
    • foreign key约束指定某一个列或一组列作为外部键,其中包含外部键的表称为子表,包含外键所引用的键的表称为父表
    • 外键的使用格式
    • 给现有表添加外键
    - alter table goods add foreign key (brand_id) references goods_brands(id);
    
    -- 若出现1452错误
    -- 错误原因:已经添加了一个不存在的cate_id值12,因此需要先删除
    
    • 创建表时添加外键
    create table goods(
        表结构的内容,
        foreign key(父表 #goods 结构中的字段) references 要引用的子表名(子表中的字段),
        foreign key(brand_id) references goods_brands(id)
    );
    

    注意: goods 中的 cate_id 的类型一定要和 goods_cates 表中的 id 类型一致

    • 删除外键约束
    -- 需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称
    -- 查勘表结构,表结构内 CONSTRAINT 后面就是外键名
    alter table goods drop FOREIGN key 外键名;
    

    外键使用时的注意点:

    • 使用到外键约束会极大的降低表更新的效率, 所以在追求读写效率优先的场景下一般很少使用外键。
    • 外键约束作用 子表中的外键字段在插入和更新 新值的时候 新值必须 在主表中相应字段出现过。

    十一、 注意项

    1、合理的选择数据类型

    选择合理范围内最小的,因为这样可以大大减少磁盘空间及磁盘I/0读写开销,减少内存占用,减少CPU的占用率。

    2、 选择相对简单的数据类型

    数字类型相对字符串类型要简单的多,尤其是在比较运算时,所以我们应该选择最简单的数据类型。

    3、列属性尽量为 NOT NULL

    MYSQL对NULL字段优化不佳,增加更多的计算难度,同时在保存与处理NULL类形时,也会做更多的工作,所以从效率上来说,不建议用过多的NULL。
    有些值他确实有可能没有值,怎么办呢?解决方法是数值弄用整数0,字符串用""来定义默认值即可。

    4、int(10)是什么含义

    代表显示宽度,整数列的显示宽度与mysql需要用多少个字符来显示该列数值,与该整数需要的存储空间的大小都没有关系。
    比如,不管设定了显示宽度是多少个字符,int都要占用4个字节。

  • 相关阅读:
    php 请求另一个服务器接口返回数据
    yii2 安装
    无限分类的
    程序员学习能力提升三要素转载
    为什么有的人工作多年还是老样子
    随笔杂谈
    Ecshop商品描述上传中文名图片无法显示解决方法
    「PSR 规范」PSR-2 编码风格规范
    leetcode 之Set Matrix Zeroes(10)
    leetcode 之Plus One(9)
  • 原文地址:https://www.cnblogs.com/yanguhung/p/10145771.html
Copyright © 2011-2022 走看看