数据库(七):单表查询

进击の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字段的数据

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

接下来就是多表查询了~


*****
*****
原文地址:https://www.cnblogs.com/jevious/p/11451343.html