MySQL--单表查询、多表查询简单概述

表的前期准备:

create table emp(
  id int not null unique auto_increment,
  name varchar(20) not null,
  sex enum('male','female') not null default 'male', #大部分是男的
  age int(3) unsigned not null default 28,
  hire_date date not null,
  post varchar(50),
  post_comment varchar(100),
  salary double(15,2),
  office int, #一个部门一个屋子
  depart_id int
);

#插入记录
#三个部门:教学,销售,运营
insert into emp(name,sex,age,hire_date,post,salary,office,depart_id) values
('jason','male',18,'20170301','张江第一帅形象代言',7300.33,401,1), #以下是教学部
('egon','male',78,'20150302','teacher',1000000.31,401,1),
('kevin','male',81,'20130305','teacher',8300,401,1),
('tank','male',73,'20140701','teacher',3500,401,1),
('owen','male',28,'20121101','teacher',2100,401,1),
('jerry','female',18,'20110211','teacher',9000,401,1),
('nick','male',18,'19000301','teacher',30000,401,1),
('sean','male',48,'20101111','teacher',10000,401,1),

('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
('丫丫','female',38,'20101101','sale',2000.35,402,2),
('丁丁','female',18,'20110312','sale',1000.37,402,2),
('星星','female',18,'20160513','sale',3000.29,402,2),
('格格','female',28,'20170127','sale',4000.33,402,2),

('张野','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬银','female',18,'20130311','operation',19000,403,3),
('程咬铜','male',18,'20150411','operation',18000,403,3),
('程咬铁','female',18,'20140512','operation',17000,403,3)
;

#ps:如果在windows系统中,插入中文字符,select的结果为空白,可以将所有字符编码统一设置成gbk

 

 

 

 

 

 

 

1、语法执行顺序:

select id,name from emp where id >= 3 and id <= 6;

# 先后顺序
from  # 确定到底是哪张表
where  # 根据过来条件 筛选条件
select  # 拿出筛选出来的数据中的某些字段

select * from emp\G; # 当表字段特别多的时候 结果的排版可能会出现混乱的现象 你可以在查询语句加入\G来规范查询的结果

 

  

 

 

 

 

2、where约束条件# 1.查询id大于等于3小于等于6的数据

select * from emp where id >= 3 and id <= 6;
select * from emp where id between 3 and 6;  # 这条语句等价于上面那条语句
# 2.查询薪资是20000或者18000或者17000的数据
select id,name from emp where salary = 20000 or salary = 18000 or salary = 17000;
select id,name from emp where salary in (20000,18000,17000);
# 3.查询员工姓名中包含o字母的员工姓名和薪资
# 模糊匹配 like
# %:匹配多个任意字符
# _:匹配一个任意字符
select name, salary from emp where name like '%o%';
# 4.查询员工姓名是由四个字符组成的员工姓名与其薪资
# 5.查询id小于3或者大于6的数据
select * from emp where id < 3 or id > 6;

  select * from emp where id not between 3 and 6;
  # 6.查询薪资不在20000,18000,17000范围的数据
  select id,name from emp where salary not in (20000,18000,17000);
  # 7.查询岗位描述为空的员工名与岗位名 针对null判断的时候只能用is 不能用=
  select name,post from emp where post_comment = Null;
  select name,post from emp where post_comment is Null;


MySQL对于大小写是不敏感的


 

 

 

 

 

 

 

group by分组

# 1.按部门分组
    select * from emp group by post;
    分组之后应该做到最小单位是组,而不应该再展示组内的单个数据信息
    
    MySQL中分组之后 只能拿到分组的字段信息 无法直接获取其他字段信息
    但是你可以通过其他方法(聚合函数)简介的获取

    如果你的MySQL不报错 说明严格模式没有设置 
    show variables like '%mode%';
    set session  当前窗口有效
    set global  全局有效 
    set global sql_mode="strict_trans_tables,only_full_group_by";

select * from emp group by post; select id,name from emp group by post; select name from emp group by post; # 2.获取每个部门的最高工资 聚合函数 max min avg sum count select post,max(salary) from emp group by post; 给字段取别名 select post as '部门',max(salary) as '最高工资' from emp group by post; select post '部门',max(salary) '最高工资' from emp group by post; # 每个部门的最低工资 select post,min(salary) from emp group by post; # 每个部门的平均工资 select post,avg(salary) from emp group by post; # 每个部门的工资总和 select post,sum(salary) from emp group by post; # 每个部门的人数 select post,count(age) from emp group by post; select post,count(salary) from emp group by post; select post,count(id) from emp group by post; select post,count(post_comment) from emp group by post; 在统计分组内个数的时候 填写任意非空字段都可以完成计数,推荐使用能够唯一标识数据的字段 比如id字段 """ 聚合函数会自动将每一个分组内的单个数据做想要的计算,无需你考虑 """ # 3.查询分组之后的部门名称和每个部门下所有的学生姓名 select post,group_concat(name) from emp group by post; select post,group_concat('DSB',name) from emp group by post; group_concat()能够拿到分组后每一个数据指定字段(可以是多个)对应的值 select post,group_concat(name,": ",salary) from emp group by post; concat select concat("NAME: ",name),concat("SAL: ",salary) from emp; 小技巧: concat就是用来帮你拼接数据 concat 不分组情况下使用 group_concat 分组之后使用 # 查询每个员工的年薪 select name,salary*12 from emp; # 刚开始查询表,一定要按照最基本的步骤,先确定是哪张表,再确定查这张表也没有限制条件,再确定是否需要分类,最后再确定需要什么字段对应的信息 """ 你应该将每一步操作产生的结果都当成是一张新的表 然后基于该表再进行其他的操作 """ 1. 查询岗位名以及岗位包含的所有员工名字group_concat 2. 查询岗位名以及各岗位内包含的员工个数count 3. 查询公司内男员工和女员工的个数count 4. 查询岗位名以及各岗位的平均薪资avg 5. 查询岗位名以及各岗位的最高薪资max 6. 查询岗位名以及各岗位的最低薪资min 7. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资avg """ 聚合函数 max min sum count avg只能在分组之后使用 如果一张表没有写group by默认所有的数据就是一组 """ 书写顺序 select from where group by 执行顺序 from where group by select 8、统计各部门年龄在30岁以上的员工平均工资 # 先获取年轻在30岁以上的员工 select post,avg(salary) from emp where age > 30 group by post; """ 写sql语句的时候 一定不要一口气写完 前期先按照步骤一步步写 写一步查询看一下结果然后基于当前结果再往后写 """

 

 

 

 

 

having

跟where是一模一样的 也是用来筛选数据
        但是having是跟在group by之后的
        where是对整体数据做一个初步的筛选
        而having是对分组之后的数据再进行一次针对性的筛选
having:跟where功能是一样的,但是having是作用在分组之后的
where是作用在分组之前的

1、统计各部门年龄在30岁以上的员工平均工资, 并且保留平均工资大于10000的部门 select post,avg(salary) from emp where age > 30 group by post having avg(salary) > 10000; select post,avg(salary) from emp where age > 30 group by post where avg(salary) > 10000; # 报错 # 强调:having必须在group by后面使用 select * from emp having avg(salary) > 10000; # 报错 执行顺序 from where group by having select

 

 

 

 

distinct去重

多重复的数据进行一个去重
    """
    去重必须数据是一模一样的才能去重
    只要有一个不一样 都不能算是的重复的数据,如果你的数据中包含主键字段,那就不可能去重成功
    """
    select distinct id,age from emp;
    
    
    
    执行顺序
    from 
    where
    group by
    having
    select
    distinct
    

 

 

 

 

 

order by:排序

默认是升序 asc
       也可以变成降序  desc
        
    select * from emp order by salary;
    select * from emp order by salary asc;
    select * from emp order by salary desc;
    select * from emp order by age,salary;   # 先按照age做升序 age相同的情况下再按照salary做升序
    select * from emp order by age asc,salary desc;   # 先按照age做升序 age相同的情况下再按照salary做升序
    
    
    # 统计各部门年龄在10岁以上的员工平均工资,
    # 并且保留平均工资大于1000的部门,然后对平均工资进行排序
    select post,avg(salary) from emp where age > 10 group by post having avg(salary) > 1000 order by avg(salary);

 

 

 

 

 

limit:限制展示数据的条数

limit  限制展示数据的条数
    select * from emp limit 5;  # 只展示数据的五条
    select * from emp limit 5,5;  
    
    """
    当limit只有一个参数的时候  表示的是限制展示个数
   当limit有两个参数的时候 第一个参数表示的起始位置(不含当前位置) 第二个参数表示从起始位置开始往后展示的条数 """ # 查询工资最高的人的详细信息 # 先按照薪资排序 # 再用limit限制 只取一条
select * from emp order by salary desc limit 1;
  
  应用场景:对数据的分页展示

 

 

 

 

正则:在编程中 只要看到reg开头的  基本上都是跟正则相关的

select * from emp where name regexp '^j.*(n|y)$';

 

 

 

 

连表查询:

  """
    表查询分为两大类
        1.联表查询
        2.子查询
    """
    select * from emp,dep;   产生的结果是一个笛卡尔积
    
    
    # 查询部门为技术部的员工及部门信息
    
    
    
    有专门帮你做连表的方法
    内连接(inner join)  只连接两张表相同的数据
    select * from emp inner join dep on dep.id = emp.dep_id; 左连接(
left join) 在内连接的基础上 保留左表没有对应的数据
    select * from emp left join dep on emp.dep_id = dep.id; 右连接(
right join) 在内连接的基础上 保留左边没有对应的数据
    select * from emp right join dep on emp.dep_id = dep.id; 全连接(
union) # 只要将左连接和右连接的sql语句 加一个union就变成全连接 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; 子查询 将一张表的查询结果作为另外一个sql语句的查询条件 select name from dep where id = (select dep_id from emp where name = 'jason'); # 2.每个部门最新入职的员工 # 思路:先查每个部门最新入职的员工,再按部门对应上联表查询 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 ; # 可以给表起别名 # 可以给查询出来的虚拟表起别名 # 可以给字段起别名

 

 

 

exist:存在

在使用exists关键字的时候,内层查询不返回查询的记录,而是返回个真假值(True 或者 False)
    当返回True的时候,外层查询语句将进行查询
    返回值为False的时候,外层查询语句不进行查询。

select
* from emp where exists(select id from dep where id > 203);

 

 

 

MySQL中的注释:

    1、--

    2、#

 

posted @ 2019-08-21 15:45  tulintao  阅读(266)  评论(0编辑  收藏  举报