• 数据库(七):单表查询


    进击のpython

    *****

    数据库——单表查询


    数据库在使用的时候,更多的是查看数据,而学会了外键之后,查询就已经不仅仅是针对单个表的操作了

    同时,对于单表的查询要求也是越来越高,而基于此,原先的简单查询就有点心有余而力不足了

    所以说,接下来就是进阶的查询!首先要确定一点的就是,查询是针对记录的,这点要明确哦


    单表查询

    既然是进阶,就一定有不一样的花板子~完整的单表查询指令如下:

    select distinct字段名1,字段名2 from 库.表 
    
    where 条件
    
    group by 分组
    
    having 过滤
    
    order by 排序
    
    limit 限制
    
    ;
    

    简单查询

    distinct:去重

    mysql> select post from employee;
    +-----------------------------------------+
    | post                                    |
    +-----------------------------------------+
    | 驻沙河办事处外交大使                       |
    | teacher                                 |
    | teacher                                 |
    | teacher                                 |
    | teacher                                 |
    | teacher                                 |
    | teacher                                 |
    | teacher                                 |
    | sale                                    |
    | sale                                    |
    | sale                                    |
    | sale                                    |
    | sale                                    |
    | operation                               |
    | operation                               |
    | operation                               |
    | operation                               |
    | operation                               |
    +-----------------------------------------+
    18 rows in set (0.00 sec)
    
    mysql> select distinct post from employee;
    +-----------------------------------------+
    | post                                    |
    +-----------------------------------------+
    | 驻沙河办事处外交大使                      |
    | teacher                                 |
    | sale                                    |
    | operation                               |
    +-----------------------------------------+
    4 rows in set (0.32 sec)
    
    

    同时查询的时候是支持四则运算的:

    mysql> select name,salary*12 from employee;
    +------------+-------------+
    | name       | salary*12   |
    +------------+-------------+
    | egon       |    87603.96 |
    | alex       | 12000003.72 |
    | wupeiqi    |    99600.00 |
    | yuanhao    |    42000.00 |
    | liwenzhou  |    25200.00 |
    | jingliyang |   108000.00 |
    | jinxin     |   360000.00 |
    | 成龙       |   120000.00 |
    | 歪歪       |    36001.56 |
    | 丫丫       |    24004.20 |
    | 丁丁       |    12004.44 |
    | 星星       |    36003.48 |
    | 格格       |    48003.96 |
    | 张野       |   120001.56 |
    | 程咬金     |   240000.00 |
    | 程咬银     |   228000.00 |
    | 程咬铜     |   216000.00 |
    | 程咬铁     |   204000.00 |
    +------------+-------------+
    18 rows in set (0.00 sec)
    
    mysql> select name,salary*12 as annual_salary from employee;
    +------------+---------------+
    | name       | annual_salary |
    +------------+---------------+
    | egon       |      87603.96 |
    | alex       |   12000003.72 |
    | wupeiqi    |      99600.00 |
    | yuanhao    |      42000.00 |
    | liwenzhou  |      25200.00 |
    | jingliyang |     108000.00 |
    | jinxin     |     360000.00 |
    | 成龙       |     120000.00 |
    | 歪歪       |      36001.56 |
    | 丫丫       |      24004.20 |
    | 丁丁       |      12004.44 |
    | 星星       |      36003.48 |
    | 格格       |      48003.96 |
    | 张野       |     120001.56 |
    | 程咬金     |     240000.00 |
    | 程咬银     |     228000.00 |
    | 程咬铜     |     216000.00 |
    | 程咬铁     |     204000.00 |
    +------------+---------------+
    18 rows in set (0.37 sec)
    
    

    看到为什么写两个了吧,看到区别了吧~

    还有就是字符串拼接,怎么拼接呢?

    select concat('name:',name) from employee;

    mysql> select concat('name:',name) from employee;
    +------------------------+
    | concat('name:',name)  |
    +------------------------+
    | name:egon             |
    | name:alex             |
    | name:wupeiqi          |
    | name:yuanhao          |
    | name:liwenzhou        |
    | name:jingliyang       |
    | name:jinxin           |
    | name:成龙             |
    | name:歪歪             |
    | name:丫丫             |
    | name:丁丁             |
    | name:星星             |
    | name:格格             |
    | name:张野             |
    | name:程咬金           |
    | name:程咬银           |
    | name:程咬铜           |
    | name:程咬铁           |
    +------------------------+
    18 rows in set (0.00 sec)
    
    

    where约束

    where字句中可以使用:

    1. 比较运算符:> < >= <= <> !=
    2. between 80 and 100 值在80到100之间
    3. in(80,90,100) 值是10或20或30
    4. like 'ponny%'
      pattern可以是%或_,
      %表示任意多字符
      _表示一个字符
    5. 逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not

    这个一部分讲的在前面都有涉及,所以,就不举例了,你自己尝试使用

    group by

    这是分组,分组就是把有相同或相似特征的放在一起

    比如说把男的都放在一起,把女的都放在一起

    而且group by 只能够查询该分组的组名,查不到别的东西

    mysql> select * from employee group by post;
    +----+--------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    | id | name   | sex    | age | hire_date  | post                                    | post_comment | salary     | office | depart_id |
    +----+--------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    | 14 | 张野   | male   |  28 | 2016-03-11 | operation                               | NULL         |   10000.13 |    403 |         3 |
    |  9 | 歪歪   | female |  48 | 2015-03-11 | sale                                    | NULL         |    3000.13 |    402 |         2 |
    |  2 | alex   | male   |  78 | 2015-03-02 | teacher                                 | NULL         | 1000000.31 |    401 |         1 |
    |  1 | egon   | male   |  18 | 2017-03-01 | 驻沙河办事处外交大使              | NULL         |    7300.33 |    401 |         1 |
    +----+--------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    4 rows in set (0.41 sec)
    
    

    你这不骗我吗?哪只有分组数据啊,这么多数据呢!

    但是你会发现打印出来的都是每组的第一条数据,这是没有意义的

    别慌,其实这是mysql的设定,我们需要把模式改成严格模式才可以

    set global sql_mode='ONLY_FULL_GROUP_BY';

    怎么设置完还这样呢?还记得设置自增时候的步长和起始偏移量的时候吗?我们需要关掉重开一下!

    mysql> select * from employee group by post;
    ERROR 1055 (42000): 't.employee.id' isn't in GROUP BY
    

    但是其实也没有用,因为分组的目的不是想看看同类的,而是想对这些人做一个数据处理

    比如像想统计人数啊之类的~~那就用到了聚合函数了!

    那题道具和函数,就得好好说或聚合函数,聚合函数一共有这些:

    max min avg sum count

    比如说我们统计一下每个职位的人数~

    select count(id) from employee group by post

    mysql> select post,count(name) from employee group by post;
    +-----------------------------------------+-------------+
    | post                                    | count(name) |
    +-----------------------------------------+-------------+
    | operation                               |           5 |
    | sale                                    |           5 |
    | teacher                                 |           7 |
    | 驻沙河办事处外交大使                	  |           1 |
    +-----------------------------------------+-------------+
    
    4 rows in set (0.00 sec)
    

    要是想打印人数大于五的部门信息那我应该是这么写:

    select concat('职位:',post,'	人数:',count(name),
    '	姓名:',group_concat(name)) as info,
    count(name)>5 from employee group by post;
    

    尤其是看到group_concat(name)的用法!!!

    你可能执行的结果是这个:

    +--------------------------------------------------------------------------------------------+--------+
    | info                                                                                       | 数量   |
    +--------------------------------------------------------------------------------------------+--------+
    | 职位:operation人数:5姓名:程咬铁,程咬铜,程咬银,程咬金,张野                               |      0 |
    | 职位:sale人数:5姓名:格格,星星,丁丁,丫丫,歪歪                                            |      0 |
    | 职位:teacher人数:7姓名:成龙,jinxin,jingliyang,liwenzhou,yuanhao,wupeiqi,alex            |      1 |
    | 职位:驻沙河办事处外交大使人数:1姓名:egon                                          |      0 |
    +--------------------------------------------------------------------------------------------+--------+
    

    这跟本来想的不一样啊!别急~~~你还差一个知识点!先放在这

    那我们可以逆向思维,如果不分组,是不是,就所有数据都是一组了!

    那是不是也可以用聚合函数!

    那我比如说想查找最高工资,是不是就会了!

    having

    这就是差的知识点!having 过滤

    诶???我好像记得之前也有个过滤,好像是where,那他们有什么区别吗?

    #!!!执行优先级从高到低:where > group by > having 
    #1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。
    
    #2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数
    

    (验证自己验证ok?)

    那饿哦们就可以接着把上面的代码优化为:

    select concat('职位:',post,'人数:',count(name),'姓名:',group_concat(name)) info from employee group by post having count(id)>5;

    这回再打印,是不是就是预料之中的结果了!

    order by

    排序

    表格默认的是id排序,那我想根据年龄排序,怎么办呢?

    select * from employee order by age;

    可以看到是默认升序,那要是想要倒序呢?

    select * from employee order by age desc

    那你可能发现age有相等的时候,那我要是想相等的时候按照id排序怎么做呢?

    select * from employee order by age,id

    limit 限制

    这个就是限制显示条数,限制显示前三条:

    mysql> select * from employee limit 3;
    +----+---------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    | id | name    | sex  | age | hire_date  | post                                    | post_comment | salary     | office | depart_id |
    +----+---------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    |  1 | egon    | male |  18 | 2017-03-01 | 沙河办事处外交大使              | NULL         |    7300.33 |    401 |         1 |
    |  2 | alex    | male |  78 | 2015-03-02 | teacher                                 | NULL         | 1000000.31 |    401 |         1 |
    |  3 | wupeiqi | male |  81 | 2013-03-05 | teacher                                 | NULL         |    8300.00 |    401 |         1 |
    +----+---------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    3 rows in set (0.09 sec)
    
    

    当然它其实还有分页的功能:

    select * from employee limit 0,5;代表着从0开始往后取5个

    (表结构看不清就看id)

     select * from employee limit 0,5;
    +----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    | id | name      | sex  | age | hire_date  | post                                    | post_comment | salary     | office | depart_id |
    +----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    |  1 | egon      | male |  18 | 2017-03-01 | 驻沙河办事处外交大使                      | NULL         |    7300.33 |    401 |         1 |
    |  2 | alex      | male |  78 | 2015-03-02 | teacher                                 | NULL         | 1000000.31 |    401 |         1 |
    |  3 | wupeiqi   | male |  81 | 2013-03-05 | teacher                                 | NULL         |    8300.00 |    401 |         1 |
    |  4 | yuanhao   | male |  73 | 2014-07-01 | teacher                                 | NULL         |    3500.00 |    401 |         1 |
    |  5 | liwenzhou | male |  28 | 2012-11-01 | teacher                                 | NULL         |    2100.00 |    401 |         1 |
    +----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    5 rows in set (0.00 sec)
    
    

    从5开始往后取五个:

    mysql> select * from employee limit 5,5;
    +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
    | id | name       | sex    | age | hire_date  | post    | post_comment | salary   | office | depart_id |
    +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
    |  6 | jingliyang | female |  18 | 2011-02-11 | teacher | NULL         |  9000.00 |    401 |         1 |
    |  7 | jinxin     | male   |  18 | 1900-03-01 | teacher | NULL         | 30000.00 |    401 |         1 |
    |  8 | 成龙       | male   |  48 | 2010-11-11 | teacher | NULL         | 10000.00 |    401 |         1 |
    |  9 | 歪歪       | female |  48 | 2015-03-11 | sale    | NULL         |  3000.13 |    402 |         2 |
    | 10 | 丫丫       | female |  38 | 2010-11-01 | sale    | NULL         |  2000.35 |    402 |         2 |
    +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
    5 rows in set (0.00 sec)
    

    接下来的分页就不演示了~

    那在这我就要提一下书写顺序和执行顺序了,毕竟约束条件这么多,总要有个优先级嘛:

    正则表达式

    where 后面虽然不能使用聚合函数,但是是可以使用正则匹配的

    selece * from employee where name regexp '^ale'; 以ale开头的

    其实他跟select * from employee where name like 'ale%';是一样的

    select * from employee where name regexp 'on$'; 以on结尾的

    select * from employee where name regexp 'm{2}'; 里面有mm的

    以上的方法都自己去试一下

    那我要是想以什么开头,以什么结尾呢?

    select * from employee where name regexp '^jin.*(g|n)$';

    这就是以 jin 开头,以g或者n结尾的name字段的数据

    那至此,所有的约束就全结束了!

    接下来就是多表查询了~


    *****
    *****
  • 相关阅读:
    解决ssh连接linux系统特别慢的问题
    mysql的InnoDB 数据库引擎TableSpace Exists 问题
    nextcloud私有云盘的部署
    su: 无法设置用户ID: 资源暂时不可用
    oracle静默安装
    mysql update 子查询锁表问题
    mysql导出数据很快,导入很慢
    mysql千万级数据库插入速度和读取速度的调整
    django, CentOS7+nginx(apache)+mod_wsgi+Python+Django
    javascript 重写已有的方法
  • 原文地址:https://www.cnblogs.com/jevious/p/11451343.html
Copyright © 2020-2023  润新知