首页 > 数据库 >MySQL查询关键字where、group by、having、distinct、order by、limit、redexp正则、多表查询之子查询、连表操作

MySQL查询关键字where、group by、having、distinct、order by、limit、redexp正则、多表查询之子查询、连表操作

时间:2022-08-17 21:58:34浏览次数:70  
标签:salary group name 查询 emp 多表 id select

目录

操作表的SQL语句补充

1.修改表名

普通方法:alter table 表名 rename 新表名;
进阶方法:rename table 表名 to 新表名;

2.查询表

select * from 表名;

3.新增字段

普通方法:alter table 表名 add 字段名 字段类型(数字) 约束条件;

指定字段添加after关键词:alter table 表名 add 字段名 字段类型(数字) 约束条件 after 已经存在的字段;

在表的最前面添加字段first关键字:alter table 表名 add 字段名 字段类型(数字) 约束条件 first;

4.修改字段

修改字段名称和类型:alter table 表名 change 旧字段 新字段 字段类型(数字) 约束条件;

只修改字段类型:alter table 表名 modify 字段名 新的字段类型(数字) 约束条件;

5.添加一列、删除一列

alter table users add column(字段  字段类型(数字))   

alter table users drop column(字段 字段类型(数字))

6.删除字段

alter table 表名 drop 字段名;

7.复制表

复制表的结构和记录 (key不会复制:主键key 外键key及索引key都不会复制)
create table new_service select * from service; 
解释:创建一个new_service表 内容为service表里的内容

只拷贝表结构(不包含键)
create table new2_service select * from service where 1=2;  
解释:这里呢是创建一个条件判定为假的条件 1肯定不等于2 所以只复制了表的框架 没有键也没有内容

拷贝表的结构并且包含键
create table new3service like service;
解释:运用到like关键字 使新表的表结构完全一样 但是没有拷贝内容。

truncate\delete\drop的区别

truncate table 和 delete只删除数据(记录)不删除表的结构;

drop语句将删除表的数据(记录)和表结构依赖的约束(constrain),触发器(trigger),索引(index),保留依赖于该表的存储过程/函数,但是变为invalid状态 .

delete 是 DML 语句,操作完以后如果没有不想提交事务还可以回滚,truncate 和 drop 是 DDL 语句,操作完马上生效,不能回滚.

查询关键字之select与from

"""
SQL语句的关键字编写顺序与执行顺序是不一致的!!!
	eg:  select name from emp;
	肯定是先支持from确定表 之后执行select确定字段
编写SQL语句针对select和from可以先写个固定模板
	select * from 表名 其他操作
select后的字段可能是实际的 也可能是通过SQL动态产生的 所以可以先用*占位最后再修改
"""
select
	自定义查询表中字段对应的数据
from
	指定操作的对象(到底是哪张表 也可能是多张)

查询关键字之where筛选

where其实就是对数据进行筛选

实例:

# 1.查询id大于等于3小于等于6的数据
写法一:
mysql> select * from emp where id >=3 and id <=6;
+----+-------+--------+-----+------------+---------+--------------+---------+--------+-----------+
| id | name  | sex    | age | hire_date  | post    | post_comment | salary  | office | depart_id |
+----+-------+--------+-----+------------+---------+--------------+---------+--------+-----------+
|  3 | kevin | male   |  81 | 2013-03-05 | teacher | NULL         | 8300.00 |    401 |         1 |
|  4 | tony  | male   |  73 | 2014-07-01 | teacher | NULL         | 3500.00 |    401 |         1 |
|  5 | owen  | male   |  28 | 2012-11-01 | teacher | NULL         | 2100.00 |    401 |         1 |
|  6 | jack  | female |  18 | 2011-02-11 | teacher | NULL         | 9000.00 |    401 |         1 |
+----+-------+--------+-----+------------+---------+--------------+---------+--------+-----------+
4 rows in set (0.00 sec)
写法二:
mysql> select * from emp where id between 3 and 6;
# 2.查询薪资是20000或者18000或者17000的数据
写法一:
mysql> select * from emp where salary =20000 or salary =18000 or salary =17000;
+----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
| id | name      | sex    | age | hire_date  | post      | post_comment | salary   | office | depart_id |
+----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
| 15 | 程咬金    | male   |  18 | 1997-03-12 | operation | NULL         | 20000.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 |
+----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+
3 rows in set (0.00 sec)
写法二:
'''MySQL也支持成员运算'''
select * from emp where salary in (20000,18000,17000);

小知识-模糊查询:

模糊查询:关键字 like
		%:匹配任意个数的任意字符
		
		_:匹配单个个数的任意字符
# 3.查询员工姓名中包含o字母的员工姓名和薪资(模糊查询)
mysql> select name,salary from emp where name like '%o%';
+-------+------------+
| name  | salary     |
+-------+------------+
| jason |    7300.33 |
| tom   | 1000000.31 |
| tony  |    3500.00 |
| owen  |    2100.00 |
+-------+------------+
4 rows in set (0.00 sec)
# 4.查询员工姓名为四个字符组成的员工姓名和薪资
写法一:
mysql> select name,salary from emp where name like '____';
+------+----------+
| name | salary   |
+------+----------+
| tony |  3500.00 |
| owen |  2100.00 |
| jack |  9000.00 |
| sank | 10000.00 |
+------+----------+
4 rows in set (0.00 sec)
写法二:
'''根据统计长度来查找'''
mysql> select name,salary from emp where char_length(name)=4;
# 5.查询id小于3或者大于6的数据
写法一:
select * from emp where id < 3 or id > 6;
写法二:取反
select * from emp where id not between 3 and 6;

查询关键字之group by 分组

按照某个指定的条件将单个单个的数据分为一个个的整体

分组之后我们研究的对象应该是以组为单位 不应该再直接获取单个数据项 如果获取了应该直接报错 select后面可以直接填写的字段名只能是分组的依据(其他字段需要借助于一些方法才可以获取)

img

img

set global sql_mode='strict_trans_tables,only_full_group_by';

mysql> use db;
Database changed
mysql> select * from emp group by post;
# ERROR 1055 (42000): 'db.emp.id' isn't in GROUP BY

此时就不可以拿到所有的数据了,是按部门分组的,将来是按照部门管理数据的

我们写SQL是否需要使用分组 可以在题目中得到答案
	每个、平均、最大、最小
	
配合分组常见使用的有聚合函数
	max			最大值
	min 		最小值
	sum 		总和
	count 		计数
	avg			平均

实例:

# 1.每个部门的最高工资
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)
# 2.每个部门的平均工资
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)
# 3.求每个部门的工资总和
mysql> select post,sum(salary) from emp group by post;
+-----------------------------+-------------+
| post                        | sum(salary) |
+-----------------------------+-------------+
| operation                   |    84000.13 |
| sale                        |    13001.47 |
| teacher                     |  1062900.31 |
| 浦东第一帅形象代言          |     7300.33 |
+-----------------------------+-------------+
4 rows in set (0.00 sec)
# 4.求每个部门的人数
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.00 sec)

小知识1-拼接:

group_concat:用来做分组以后,获取除分组依据以外的一些字段,可以是一个也可以是多个,字段与字段之间可以设置一些分割符号
    
concat 用户分组之前的拼接操作

concat_ws 当多个字段链接符相同的情况下推荐使用
# 5.查询分组之后的部门名称和每个部门下所有的员工姓名
mysql> select post,group_concat(name) from emp group by post;
+-----------------------------+------------------------------------------------+
| post                        | group_concat(name)                             |
+-----------------------------+------------------------------------------------+
| operation                   | 程咬铁,程咬铜,程咬银,程咬金,僧龙               |
| sale                        | 拉拉,乐乐,西西,呵呵,哈哈                       |
| teacher                     | sank,jenny,jack,owen,tony,kevin,tom            |
| 浦东第一帅形象代言          | jason                                          |
+-----------------------------+------------------------------------------------+
4 rows in set (0.00 sec)

mysql> select post,group_concat(name,':',salary) from emp group by post;
+-----------------------------+--------------------------------------------------------------------------------------------------+
| post                        | group_concat(name,':',salary)                                                                    |
+-----------------------------+--------------------------------------------------------------------------------------------------+
| operation                   | 程咬铁:17000.00,程咬铜:18000.00,程咬银:19000.00,程咬金:20000.00,僧龙:10000.13                    |
| sale                        | 拉拉:4000.33,乐乐:3000.29,西西:1000.37,呵呵:2000.35,哈哈:3000.13                                 |
| teacher                     | sank:10000.00,jenny:30000.00,jack:9000.00,owen:2100.00,tony:3500.00,kevin:8300.00,tom:1000000.31 |
| 浦东第一帅形象代言          | jason:7300.33                                                                                    |
+-----------------------------+--------------------------------------------------------------------------------------------------+
4 rows in set (0.00 sec)

小知识2-分组起别名:

分组起别名:
	在查看结果的时候可以给字段起别名
	select post as '部门',max(salary) as '最高薪资' from emp group by post;
省略as:
	select post '部门',max(salary) as '最高薪资' from emp group by post;
	as可以省略但是为了语义更加明确建议不要省略

image-20220817190324609

查询关键字之having过滤

where与having的功能其实是一样的 都是用来筛选数据

只不过where用于分组之前的筛选 而having用于分组之后的筛选

为了人为的区分 所以叫where是筛选 having是过滤

实例:

# 统计各部门年龄在30岁以上的员工平均工资,并且保留平均工资大于10000
select * from emp where age > 30; 获取到的是所有年龄大于30的员工数据

mysql> select post,group_concat(name) from emp where age>30 group by post;

mysql> 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 having avg(salary)>10000;

关键字的使用顺序:where--group by--having

image-20220817190237319

查询关键字之distinct去重

去重的前提是存在一摸一样的数据,如果针对于主键肯定无法去重
关键字:distinct

实例:

1、针对于主键没有效果:
mysql> select distinct id,age from emp;
+----+-----+
| id | age |
+----+-----+
|  1 |  18 |
|  2 |  78 |
|  3 |  81 |
|  4 |  73 |
|  5 |  28 |
|  6 |  18 |
|  7 |  18 |
|  8 |  48 |
|  9 |  48 |
| 10 |  38 |
| 11 |  18 |
| 12 |  18 |
| 13 |  28 |
| 14 |  28 |
| 15 |  18 |
| 16 |  18 |
| 17 |  18 |
| 18 |  18 |
+----+-----+
18 rows in set (0.00 sec)
   
mysql> select distinct id,distinct age from emp;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'distinct age from emp' at line 1

2、查看有几个年龄段的员工:
mysql> select distinct age from emp;
+-----+
| age |
+-----+
|  18 |
|  78 |
|  81 |
|  73 |
|  28 |
|  48 |
|  38 |
+-----+
7 rows in set (0.00 sec)

查询关键字之order by排序

"""
关键字:  
	关键字需要用在指定字段之后
	asc升序(默认)、desc降序 
"""

select * from emp order by salary asc; #默认升序排
select * from emp order by salary desc; #降序排

select * from emp order by age desc; #降序排

#先按照age降序排,在年轻相同的情况下再按照薪资升序排,可以自己定义是升序还是降序
select * from emp order by age desc,salary asc; 

# 统计各部门年龄在10岁以上的员工平均工资,并且保留平均工资大于1000的部门,然后对平均工资进行排序
mysql> select post,avg(salary) from emp where age > 10 group by post having avg(salary) > 1000 order by avg(salary);
+-----------------------------+---------------+
| post                        | avg(salary)   |
+-----------------------------+---------------+
| sale                        |   2600.294000 |
| 浦东第一帅形象代言          |   7300.330000 |
| operation                   |  16800.026000 |
| teacher                     | 151842.901429 |
+-----------------------------+---------------+
4 rows in set (0.00 sec)

image-20220817190156144

查询关键字之limit分页

在查看的数据太多情况下,使用分页来限制每次查看数据的数量。

关键字: limit

用法:limit 数字
1、limit后只跟一个数字:从头开始展示多少行
	select * from emp limit 5;    # 从头开始展示5行
	
2、limit后跟两个数字:第一个数字为起始位,第二个数字为从起始位开始展示多少行
	select * from emp limit 5,5;   # 从第5行开始展示5行
	

实例:

# 求薪资最高的员工所有数据
分析:可以使用order by使薪资降序排序
	 在使用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 | tom  | male |  78 | 2015-03-02 | teacher | NULL         | 1000000.31 |    401 |         1 |
+----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
1 row in set (0.00 sec)

image-20220817190136105

查询关键字之regexp正则表达式

正则表达式:使用一些符号的组合产生一些特殊的含义,然后去字符串中筛选出符合条件的数据

关键字:regexp

实例:

# 取指定员工信息
mysql> select * from emp where name regexp '^j.*(n|y)$';
+----+-------+------+-----+------------+-----------------------------+--------------+----------+--------+-----------+
| id | name  | sex  | age | hire_date  | post                        | post_comment | salary   | office | depart_id |
+----+-------+------+-----+------------+-----------------------------+--------------+----------+--------+-----------+
|  1 | jason | male |  18 | 2017-03-01 | 浦东第一帅形象代言          | NULL         |  7300.33 |    401 |         1 |
|  7 | jenny | male |  18 | 1900-03-01 | teacher                     | NULL         | 30000.00 |    401 |         1 |
+----+-------+------+-----+------------+-----------------------------+--------------+----------+--------+-----------+
2 rows in set (0.00 sec)
解释:取员工姓名为:开头为j结尾为n或者y中间是任意字符的所有信息

image-20220817190712934

查询关键字之exists判断

定义:exists关键字表示存在,在使用在使用exists关键字时,内层查询语句不返回查询的记录,而是返回一个真假值,True或False。 

当返回为True时,外层查询语句将进行查询、
返回值为False时,外层查询语句不进行查询。

用法:sql语句 exists(判断语句) 
判断语句为True则执行sql语句 如果返回为False则不执行.

实例:

select * from emp where exists (select id from emp where id > 3);
解释:括号内判断语句为True有结果则会执行exists前的sql语句

select * from emp where exists (select id from emp where id > 20);
解释:括号内判断语句为False没有结果则不会执行exists前的sql语句

image-20220817192405321

多表查询的思路

子查询
	将一张表的查询结果括号括起来当做另外一条SQL语句的条件
        eg:类似以日常生活中解决问题的方式
			第一步干什么
			第二步基于第一步的结果在做操作 ...
               
连表操作
	先将所有涉及到结果的表全部拼接到一起形成一张大表 然后从大表中查询数据

多表查询之子查询

其实就是分布操作 将一张表的查询结果当作另外一条sql语句的查询条件

实例:

# 查询jason的部门名称
1.先获取Jason的部门编号
	select dep_id from emp1 where name = 'jason';
2.根据部门编号获取名称
	select name from dep1 where id = 200;
结合起来:
    mysql> select name from dep1 where id = (select dep_id from emp1 where name = 'jason');
    +--------+
    | name   |
    +--------+
    | 技术   |
    +--------+
    1 row in set (0.00 sec)

image-20220817200946863

多表查询连表操作

1、from 后可跟多个表用逗号隔开,使两张表拼接
	eg :from emp1,dep1-----这个现象称为笛卡儿积

2、在涉及到多表操作的时候 为了避免表字段重复
	需要在字段名的前面加上表名限制

image-20220817204555068

实例:

image-20220817205133618

select emp1.name,dep1.name from emp1,dep1 where emp1.dep_id=dep1.id;

但是这种写法效率太低不建议写

'''专门的语法:'''
inner join		内连接
	只拼接两边都有的字段数据
left join		左连接
	以左表为基准 展示所有的数据 没有对应则NULL填充
right join		右连接
	以右表为基准 展示所有的数据 没有对应则NULL填充
union		   全连接
	select * from emp1 left join dep1 on emp1.dep_id = dep1.id
   	union
	select * from emp1 right join dep1 on emp1.dep_id = dep1.id;

练习题

完成下列练习题
#1. 查询岗位名以及岗位包含的所有员工名字
mysql> select dep1.name,emp1.name from emp1 right join dep1 on  emp1.dep_id = dep1.id;
+--------------+--------+
| name         | name   |
+--------------+--------+
| 技术         | jason  |
| 人力资源     | dragon |
| 人力资源     | kevin  |
| 销售         | nick   |
| 运营         | owen   |
| 安保         | NULL   |
+--------------+--------+
#2. 查询岗位名以及各岗位内包含的员工个数
mysql> select dep1.name,count(emp1.name) from emp1 right join dep1 on  emp1.dep_id = dep1.id group by dep1.name;
+--------------+------------------+
| name         | count(emp1.name) |
+--------------+------------------+
| 人力资源     |                2 |
| 安保         |                0 |
| 技术         |                1 |
| 运营         |                1 |
| 销售         |                1 |
+--------------+------------------+
5 rows in set (0.00 sec)
#3. 查询公司内男员工和女员工的个数
mysql> select gender as '性别',count(1) as '数量' from emp1 group by gender;
+--------+--------+
| 性别   | 数量   |
+--------+--------+
| male   |      4 |
| female |      2 |
+--------+--------+
2 rows in set (0.00 sec)
#4. 查询岗位名以及各岗位的平均薪资
mysql> select dep.name,avg(emp.salary) from emp right join dep on  emp.office = dep.id group by dep.name;
+-----------+-----------------+
| name      | avg(emp.salary) |
+-----------+-----------------+
| 教学部    |   133775.080000 |
| 运维部    |    16800.026000 |
| 销售部    |     2600.294000 |
+-----------+-----------------+
3 rows in set (0.00 sec)
#5. 查询岗位名以及各岗位的最高薪资
mysql> select dep.name,max(emp.salary) from emp right join dep on  emp.office = dep.id group by dep.name;
+-----------+-----------------+
| name      | max(emp.salary) |
+-----------+-----------------+
| 教学部    |      1000000.31 |
| 运维部    |        20000.00 |
| 销售部    |         4000.33 |
+-----------+-----------------+
3 rows in set (0.00 sec)
#6. 查询岗位名以及各岗位的最低薪资
mysql> select dep.name,min(emp.salary) from emp right join dep on  emp.office = dep.id group by dep.name;
+-----------+-----------------+
| name      | min(emp.salary) |
+-----------+-----------------+
| 教学部    |         2100.00 |
| 运维部    |        10000.13 |
| 销售部    |         1000.37 |
+-----------+-----------------+
3 rows in set (0.00 sec)
#7. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
#8. 统计各部门年龄在30岁以上的员工平均工资
#9. 统计各部门年龄在10岁以上的员工平均工资,并且保留平均工资大于1000的部门,然后对平均工资进行排序

标签:salary,group,name,查询,emp,多表,id,select
From: https://www.cnblogs.com/zxr1002/p/16596886.html

相关文章

  • MySQL之查询关键字
    今日内容操作表的SQL语句补充1.修改表名 altertable表名remane新表名;2.新增字段 altertable表名add字段名字段类型(数字)约束条件; altertable表名add......
  • Mysql使用实际01---SQL分组查询
    1.SQL分组查询使用场景对记录的分组是通过关键字GROUPBY实现的,GROUPBY后面跟着一个定义组的构成的属性列表。 如果我们使用语句GROUPBYA1,……,Ak我们就把记......
  • 【MySQL】多表查询:自连接VS非自连接
    区别:多表查询时是否和自身连接(自恋)1.自连接查询员工last_name和他的领导名称SELECTCONCAT(worker.last_name,'的领导是',manager.last_name)FROMemployeesworke......
  • 【MySQL】多表查询:等值连接VS非等值连接
    区别:多表查询中的where条件是否相等1.等值连接查询员工的employee_id,last_name,department_name,citySELECTe.last_name,d.department_name,l.cityFROMemployeese,......
  • 表操作与数据查询
    关于表的操作[]添加字段altertablet1addgendervarchar(32)deault"male";指定在某个字段后添加altertablet1addhobbyvarchar(32)aftername;在开头......
  • Winform下拉框使用拼音首字母查询
    项目需要一个搜索所在单位的选项,因为选项众多需要用下拉框来进行选择。众多选择为了更好的使用,采用了拼音首字母进行查询。显示的效果如果下:在输入框输入X出现X相关的单......
  • 查询信息系统项目管理师2022年上半年考试成绩,意外通过,给自己点个赞!
    原本准备的是2021年下半年的考试,因成都疫情影响,准考证都打印出来了,结果临时取消了。终于2022年上半年的考试得以进行,殊为不易。考试在5月28日,这次考试内容变化有些大,刚考......
  • 第39关--堆叠查询,整形注入
     先进行判断是否存在注入:?id=1and1=1  接着?id=1and1=2进行判断找出注入点是整形还是字符型注入  ?id=1and1=2--+ 返回异常。说明是整形注入  判断......
  • MGR 重要参数-group_replication_consistency
    参数group_replication_consistency共5个值可选:1.EVENTUAL:确保最终一致性,并不能保证数据实时同步。(MySQL8.0.14之前只有这一个选项)2.BEFORE:确保本地强一致性,并不......
  • k8s 集群节点 SLUB: Unable to allocate memory on node -1 cgroup 内存泄露问题
    1.原因cgroup的kmemaccount特性在3.x内核上有内存泄露问题,如果开启了kmemaccount特性会导致可分配内存越来越少,直到无法创建新pod或节点异常几点解释:kmema......