day40-记录的增删改查、单表查询、多表查询、子查询

 记录的境、删、改

1、  跟权限有关的几张表

user--->db--->table-priv--->columns_priv
用户--->库-->列表权限--->字段权限

2、只创建账号

create user tom@"客户端的Ip" identified by "123";

create user tom@"192.168.15.%" identified by "123";    #192.168.15.%取的是客户端192.168.15网段的任意IP地址

create user tom@"%" identified by “123”;    # %为任意IP地址

#客户端:192.168.15.13               服务端:192.168.15.90
create user tom@"192.168.15.13" identified by "123";
mysql -utom -p"123" -h 192.168.15.90 -P 3306    #-p:密码,-h:主机ip地址,-P:端口

3、创建账号并且授权(只有root账号才能为其他账号授权grant)

#*.* ===> mysql.user    #针对用户的权限
grant all on *.* to "tom"@"192.168.15.90" identified by "123" ;    #all代表除了grant以外的所有权限

#db1.* ===>mysql.db    #针对库的权限
grant all on db1.* to "jack"@"192.168.15.90" identified by "123";    #all代表除了grant以外的所有权限

#db1.t1===>mysql.tables_priv    #针对列表的权限
grant all on db1.t1 to "rose"@"192.168.15.90" identified by "123";     #all代表除了grant以外的所有权限

# db1.t1(id) ===> mysql.columns_priv    #针对字段的权限
grant select(id),update(name) on db1.t1 to "lili"@"192.168.15.90" identified by "123";

# 修改完权限一定要
flush privileges;    #刷新权限

#删除权限

drop user "tom"@"192.168.15.90";
drop user "jack"@"192.168.15.90";
drop user "rose"@"192.168.15.90";
drop user "lili"@"192.168.15.90";
flush privileges;

单表查询

1、完整的语法(语法级别关键字的排列顺序如下 )
select distinct 字段1,字段2,字段3,... from 库名.表名
                    where 约束条件
                    group by 分组依据
                    having 过滤条件
                    order by 排序的字段
                    limit 限制显示的条数
                    ;
# 必须要有的关键字如下:

select * from t1;

关键字的执行的优先级

from
where
group by
having
distinct
order by
limit

相当于函数执行顺序:

def from():
    pass

def where():
    pass

def group():
    pass

def having():
    pass

def distinct():
    pass

def order():
    pass

def limit():
    pass

def select():
    f=from()
    res1=where(f)
    res2=group(res1)
    res3=having(res2)
    res4=distinct(res3)
    res5=order(res4)
    limit(res5)

1、简单查询

select * from t1;    #查询t1列表所有字段的信息
select id,name,sex from t1;    #查询t1列表的id,name,sex字段信息
select distinct post from emp;    #distinct:结果去重
select name,salary*12 as annual_salary from emp;    #查询emp表中name字段信息以及salary*12命名为annual_salary字段信息

select concat('名字: ',name) as new_name,concat("年龄: ",age) as new_age from emp;    #as为在前面产生的信息放在后面产生字段名下,concat函数可以连接一个或者多个字符串,若其中一个为null,则返回null

select concat(name,":",age) from emp;    #在name和age之间用:来分隔开

select concat(name,":",age,":",sex) from emp;    #在多个字符串之间用:来分隔开
select concat_ws(":",name,age,sex) as info from emp;    #concat_ws是在括号内多个字符串进行“:”格式分隔
 SELECT
       (
           CASE  # 开始标识符
           WHEN NAME = 'egon' THEN
               NAME
           WHEN NAME = 'alex' THEN
               CONCAT(name,'_BIGSB')
           ELSE
               concat(NAME, 'SB')
           END    #结尾标识符
       ) as new_name
   FROM
       emp;

上图代码,下图结果:

2、where用法

select * from emp where id >=10 and id <=15;  #等同于select * from emp where id between 10 and 15;     #查询id在10~15之间的信息
select * from emp where id = 6 or id =9 or id =12;    # 等同于select * from emp where id in (6,9,12);    #查询id为6、9、12的信息
_代表任意单个字符
%代表任意无穷个字符
select * from emp where name like "__";    #查询匹配两位字符的信息
select * from emp where name like "jin%";    #查询jin+任意字符的信息
select * from emp where id not in (6,9,12);    #查询id不为6、9、12的信息
select * from emp where id not between 10 and 15;    #查询id不在10~15之间的信息

3、group by分组
什么是分组:按照所有记录相同的部分进行归类,一定区分度低的字段
为何要分组:当我们要以组为单位进行统计时就必须分组,分组的目的是为了以组为单位进行统计的,再去考虑单条记录毫无意义

set global sql_mode="strict_trans_tables,only_full_group_by"    #设置为严格模式,并且只能取分组字段以及聚合的结果

注意:分组之后,只能查到分组的字段以及组内金条记录聚合的成果
 

select * from emp group by post;    #查询emp列表通过post进行分组显示
原组:
mysql> select * from emp;
+----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
| 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 |
|  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 |
| 11 | 丁丁       | female |  18 | 2011-03-12 | sale                                    | NULL         |    1000.37 |    402 |         2 |
| 12 | 星星       | female |  18 | 2016-05-13 | sale                                    | NULL         |    3000.29 |    402 |         2 |
| 13 | 格格       | female |  28 | 2017-01-27 | sale                                    | NULL         |    4000.33 |    402 |         2 |
| 14 | 张野       | male   |  28 | 2016-03-11 | operation                               | NULL         |   10000.13 |    403 |         3 |
| 15 | 程咬金     | male   |  18 | 1997-03-12 | operation                               | NULL         |   20000.00 |    403 |         3 |
| 16 | 程咬银     | female |  18 | 2013-03-11 | operation                               | NULL         |   19000.00 |    403 |         3 |
| 17 | 程咬铜     | male   |  18 | 2015-04-11 | operation                               | NULL         |   18000.00 |    403 |         3 |
| 18 | 程咬铁     | female |  18 | 2014-05-12 | operation                               | NULL         |   17000.00 |    403 |         3 |
+----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
18 rows in set (0.00 sec)

结果处理:
mysql> select * from emp 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.00 sec)

聚合函数
max:取最大值
min:取最小值
avg:取平均值
sum:取和值
count:取次数值

select post,count(id) from emp group by post;    #在emp表中通过post字段进行分组
结果:
mysql> select post,count(id) from emp group by post;
+-----------------------------------------+-----------+
| post                                    | count(id) |
+-----------------------------------------+-----------+
| operation                               |         5 |
| sale                                    |         5 |
| teacher                                 |         7 |
| 老男孩驻沙河办事处外交大使              |         1 |
+-----------------------------------------+-----------+
4 rows in set (0.01 sec)
select post,max(salary) from emp group by post;    #通过post进行分组
结果:
mysql> select post,max(salary) from emp group by post;
+-----------------------------------------+-------------+
| post                                    | max(salary) |
+-----------------------------------------+-------------+
| operation                               |    20000.00 |
| sale                                    |     4000.33 |
| teacher                                 |  1000000.31 |
| 老男孩驻沙河办事处外交大使                 |     7300.33 |
+-----------------------------------------+-------------+
4 rows in set (0.00 sec)
select post,avg(salary) from emp group by post;
结果:
mysql> select post,avg(salary) from emp group by post;
+-----------------------------------------+---------------+
| post                                    | avg(salary)   |
+-----------------------------------------+---------------+
| operation                               |  16800.026000 |
| sale                                    |   2600.294000 |
| teacher                                 | 151842.901429 |
| 老男孩驻沙河办事处外交大使                  |   7300.330000 |
+-----------------------------------------+---------------+
4 rows in set (0.00 sec)
select sex,count(sex) from emp group by sex;
结果:
mysql> select sex,count(sex) from emp group by sex;
+--------+------------+
| sex    | count(sex) |
+--------+------------+
| male   |         10 |
| female |          8 |
+--------+------------+
2 rows in set (0.00 sec)
# 统计出每个部门年龄30以上的员工的平均薪资
select post,avg(salary) from emp where age >= 30 group by post;
结果:
mysql> select post,avg(salary) from emp where age >= 30 group by post;
+---------+---------------+
| post    | avg(salary)   |
+---------+---------------+
| sale    |   2500.240000 |
| teacher | 255450.077500 |
+---------+---------------+
2 rows in set (0.00 sec)
# 注意:分组是在where之后发生的
mysql> select * from emp where max(salary) > 3000;
ERROR 1111 (HY000): Invalid use of group function
# group_concat:    和concat()一样,将多个字符串连接成一个字符串,但是可以一次性指定分隔符~(concat_ws就是concat with separator)
select post,group_concat(name,':',age) from emp group by post;
结果:
mysql> select post,group_concat(name,':',age) from emp group by post;
+-----------------------------------------+------------------------------------------------------------------------------+
| post                                    | group_concat(name,':',age)                                                   |
+-----------------------------------------+------------------------------------------------------------------------------+
| operation                               | 程咬铁:18,程咬铜:18,程咬银:18,程咬金:18,张野:28                              |
| sale                                    | 格格:28,星星:18,丁丁:18,丫丫:38,歪歪:48                                      |
| teacher                                 | 成龙:48,jinxin:18,jingliyang:18,liwenzhou:28,yuanhao:73,wupeiqi:81,alex:78   |
| 老男孩驻沙河办事处外交大使              | egon:18                                                                      |
+-----------------------------------------+------------------------------------------------------------------------------+
4 rows in set (0.00 sec)

4、having 过滤条件
# where是在分组之前的过滤,即在分组之前做了一次整体性的筛选
# having是在分组之后的过滤,即在分组之后专门针对聚合的结果进行进一步的筛选

select post,avg(salary) from emp group by post having avg(salary) > 10000;
结果:
+-----------+---------------+
| post      | avg(salary)   |
+-----------+---------------+
| operation |  16800.026000 |
| teacher   | 151842.901429 |
+-----------+---------------+
2 rows in set (0.00 sec)

5、order by排序

select * from emp order by age asc; # 默认asc升序-》从小到大
结果:

select * from emp order by age desc;# desc降序-》从大到小
结果:

select * from emp order by age asc,salary desc; # 先按照age升序排列,如果age相同则按照salary降序排

6、limit 限制显示的条件

select * from emp limit 3;
结果:
mysql> select * from emp 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.00 sec)
#薪资最高那个人的详细信息
select * from emp order by salary desc limit 1;
结果:
mysql> select * from emp order by salary desc limit 1;
+----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
| id | name | sex  | age | hire_date  | post    | post_comment | salary     | office | depart_id |
+----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
|  2 | alex | male |  78 | 2015-03-02 | teacher | NULL         | 1000000.31 |    401 |         1 |
+----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
1 row in set (0.00 sec)
# 分页显示
select * from emp limit 0,5; # 从0开始往后取5条
select * from emp limit 5,5; #从5开始往后取5条
#正则表达式
select * from emp where name regexp "^jin.*(g|n)$";

03 多表查询

1、笛卡尔积

select * from emp,dep;
两表之间两两相互建立对应关系
结果:
mysql> select * from emp,dep;
+----+------------+--------+------+--------+------+--------------+
| id | name       | sex    | age  | dep_id | id   | name         |
+----+------------+--------+------+--------+------+--------------+
|  1 | egon       | male   |   18 |    200 |  200 | 技术         |
|  1 | egon       | male   |   18 |    200 |  201 | 人力资源     |
|  1 | egon       | male   |   18 |    200 |  202 | 销售         |
|  1 | egon       | male   |   18 |    200 |  203 | 运营         |
|  2 | alex       | female |   48 |    201 |  200 | 技术         |
|  2 | alex       | female |   48 |    201 |  201 | 人力资源     |
|  2 | alex       | female |   48 |    201 |  202 | 销售         |
|  2 | alex       | female |   48 |    201 |  203 | 运营         |
|  3 | wupeiqi    | male   |   38 |    201 |  200 | 技术         |
|  3 | wupeiqi    | male   |   38 |    201 |  201 | 人力资源     |
|  3 | wupeiqi    | male   |   38 |    201 |  202 | 销售         |
|  3 | wupeiqi    | male   |   38 |    201 |  203 | 运营         |
|  4 | yuanhao    | female |   28 |    202 |  200 | 技术         |
|  4 | yuanhao    | female |   28 |    202 |  201 | 人力资源     |
|  4 | yuanhao    | female |   28 |    202 |  202 | 销售         |
|  4 | yuanhao    | female |   28 |    202 |  203 | 运营         |
|  5 | liwenzhou  | male   |   18 |    200 |  200 | 技术         |
|  5 | liwenzhou  | male   |   18 |    200 |  201 | 人力资源     |
|  5 | liwenzhou  | male   |   18 |    200 |  202 | 销售         |
|  5 | liwenzhou  | male   |   18 |    200 |  203 | 运营         |
|  6 | jingliyang | female |   18 |    204 |  200 | 技术         |
|  6 | jingliyang | female |   18 |    204 |  201 | 人力资源     |
|  6 | jingliyang | female |   18 |    204 |  202 | 销售         |
|  6 | jingliyang | female |   18 |    204 |  203 | 运营         |
+----+------------+--------+------+--------+------+--------------+
24 rows in set (0.00 sec)
select * from emp,dep where emp.dep_id = dep.id;    #进一步筛选
结果:
mysql> select * from emp,dep where emp.dep_id = dep.id;
+----+-----------+--------+------+--------+------+--------------+
| id | name      | sex    | age  | dep_id | id   | name         |
+----+-----------+--------+------+--------+------+--------------+
|  1 | egon      | male   |   18 |    200 |  200 | 技术         |
|  2 | alex      | female |   48 |    201 |  201 | 人力资源     |
|  3 | wupeiqi   | male   |   38 |    201 |  201 | 人力资源     |
|  4 | yuanhao   | female |   28 |    202 |  202 | 销售         |
|  5 | liwenzhou | male   |   18 |    200 |  200 | 技术         |
+----+-----------+--------+------+--------+------+--------------+
5 rows in set (0.00 sec)
select * from emp,dep where emp.dep_id = dep.id and dep.name = "技术";    #进一步筛选
结果:
mysql> select * from emp,dep where emp.dep_id = dep.id and dep.name = "技术";
+----+-----------+------+------+--------+------+--------+
| id | name      | sex  | age  | dep_id | id   | name   |
+----+-----------+------+------+--------+------+--------+
|  1 | egon      | male |   18 |    200 |  200 | 技术   |
|  5 | liwenzhou | male |   18 |    200 |  200 | 技术   |
+----+-----------+------+------+--------+------+--------+
2 rows in set (0.01 sec)

2、内连接:只取两张表有对应关系的记录

select * from emp inner join dep on emp.dep_id = dep.id;
等同于:select * from emp,dep where emp.dep_id = dep.id;
结果:
mysql> select * from emp inner join dep on emp.dep_id = dep.id;
+----+-----------+--------+------+--------+------+--------------+
| id | name      | sex    | age  | dep_id | id   | name         |
+----+-----------+--------+------+--------+------+--------------+
|  1 | egon      | male   |   18 |    200 |  200 | 技术         |
|  2 | alex      | female |   48 |    201 |  201 | 人力资源     |
|  3 | wupeiqi   | male   |   38 |    201 |  201 | 人力资源     |
|  4 | yuanhao   | female |   28 |    202 |  202 | 销售         |
|  5 | liwenzhou | male   |   18 |    200 |  200 | 技术         |
+----+-----------+--------+------+--------+------+--------------+
5 rows in set (0.00 sec)
select * from emp inner join dep on emp.dep_id = dep.id where dep.name = "技术";
效果等同于:select * from emp,dep where emp.dep_id = dep.id and dep.name = "技术"; 
结果:
mysql> select * from emp inner join dep on emp.dep_id = dep.id
    ->                             where dep.name = "技术";
+----+-----------+------+------+--------+------+--------+
| id | name      | sex  | age  | dep_id | id   | name   |
+----+-----------+------+------+--------+------+--------+
|  1 | egon      | male |   18 |    200 |  200 | 技术   |
|  5 | liwenzhou | male |   18 |    200 |  200 | 技术   |
+----+-----------+------+------+--------+------+--------+
2 rows in set (0.00 sec)

3、左连接:在内连接的基础上保留左表没有对应关系的记录;

select * from emp left join dep on emp.dep_id = dep.id;
结果:
mysql> select * from emp left join dep on emp.dep_id = dep.id;
+----+------------+--------+------+--------+------+--------------+
| id | name       | sex    | age  | dep_id | id   | name         |
+----+------------+--------+------+--------+------+--------------+
|  1 | egon       | male   |   18 |    200 |  200 | 技术         |
|  5 | liwenzhou  | male   |   18 |    200 |  200 | 技术         |
|  2 | alex       | female |   48 |    201 |  201 | 人力资源     |
|  3 | wupeiqi    | male   |   38 |    201 |  201 | 人力资源     |
|  4 | yuanhao    | female |   28 |    202 |  202 | 销售         |
|  6 | jingliyang | female |   18 |    204 | NULL | NULL         |
+----+------------+--------+------+--------+------+--------------+
6 rows in set (0.00 sec)

4、右连接: 在内连接的基础上保留右表没有对应关系的记录

select * from emp right join dep on emp.dep_id = dep.id;
结果:
mysql> select * from emp right join dep on emp.dep_id = dep.id;
+------+-----------+--------+------+--------+------+--------------+
| id   | name      | sex    | age  | dep_id | id   | name         |
+------+-----------+--------+------+--------+------+--------------+
|    1 | egon      | male   |   18 |    200 |  200 | 技术         |
|    2 | alex      | female |   48 |    201 |  201 | 人力资源     |
|    3 | wupeiqi   | male   |   38 |    201 |  201 | 人力资源     |
|    4 | yuanhao   | female |   28 |    202 |  202 | 销售         |
|    5 | liwenzhou | male   |   18 |    200 |  200 | 技术         |
| NULL | NULL      | NULL   | NULL |   NULL |  203 | 运营         |
+------+-----------+--------+------+--------+------+--------------+
6 rows in set (0.00 sec)

5、全连接:在内连接的基础上保留左、右面表没有对应关系的的记录

select * from emp left join dep on emp.dep_id = dep.id union select * from emp right join dep on emp.dep_id = dep.id;

结果:
mysql> select * from emp left join dep on emp.dep_id = dep.id
    -> union
    -> select * from emp right join dep on emp.dep_id = dep.id;
+------+------------+--------+------+--------+------+--------------+
| id   | name       | sex    | age  | dep_id | id   | name         |
+------+------------+--------+------+--------+------+--------------+
|    1 | egon       | male   |   18 |    200 |  200 | 技术         |
|    5 | liwenzhou  | male   |   18 |    200 |  200 | 技术         |
|    2 | alex       | female |   48 |    201 |  201 | 人力资源     |
|    3 | wupeiqi    | male   |   38 |    201 |  201 | 人力资源     |
|    4 | yuanhao    | female |   28 |    202 |  202 | 销售         |
|    6 | jingliyang | female |   18 |    204 | NULL | NULL         |
| NULL | NULL       | NULL   | NULL |   NULL |  203 | 运营         |
+------+------------+--------+------+--------+------+--------------+
7 rows in set (0.00 sec)

04 子查询
子查询:就是将一个查询语句的结果用括号括起来当作另外一个查询语句的条件去用

select * from emp where dep_id in (select id from dep where name = "技术" or name = "人力资源");
括号内的结果:
mysql> select id from dep where name = "技术" or name = "人力资源"
    -> ;
+------+
| id   |
+------+
|  200 |
|  201 |
+------+
2 rows in set (0.00 sec)
整体执行结果:
mysql> select * from emp where dep_id in (select id from dep where name = "技术" or name = "人力资源");
+----+-----------+--------+------+--------+
| id | name      | sex    | age  | dep_id |
+----+-----------+--------+------+--------+
|  1 | egon      | male   |   18 |    200 |
|  2 | alex      | female |   48 |    201 |
|  3 | wupeiqi   | male   |   38 |    201 |
|  5 | liwenzhou | male   |   18 |    200 |
+----+-----------+--------+------+--------+
4 rows in set (0.00 sec)

注意:如果括号内只有一种查询结果,就需要在dep_id 后加 = 即可,如果查询结果为多种时需要用in.
# 每个部门最新入职的员工
select t1.id,t1.name,t1.hire_date,t1.post,t2.* from emp as t1
inner join
(select post,max(hire_date) as max_date from emp group by post) as t2
on t1.post = t2.post
where t1.hire_date = t2.max_date
;
#注意:命令中的as后的t1,t2,max_data为别名,为的是后期方便引用as前所得出的结果,只在本命令中有效果

上图命令中:
(select post,max(hire_date) as max_date from emp group by post) as t2

select t1.id,t1.name,t1.hire_date,t1.post,t2.* from emp as t1

t2.*为t2列表中所有字段信息=上上图中的结果。

最终结果:

select语句关键字的定义顺序:

SELECT DISTINCT <select_list>
FROM <left_table>
<join_type> JOIN <right_table>
ON <join_condition>
WHERE <where_condition>
GROUP BY <group_by_list>
HAVING <having_condition>
ORDER BY <order_by_condition>
LIMIT <limit_number>

猜你喜欢

转载自blog.csdn.net/qq_17513503/article/details/81174104