MySQL之表查询

语法执行顺序

  

from >>>从那张表

where >>> 全局的筛选条件

group by>>> 必须是用在where  之后

having >>> 和group by 一起连用 必须放在group by 之后

oder by 对于晒选出来的结果 进行 排序 默认asc 升序 desc 是降序

distinct  >>> 去重 必须是在select展示结果的时候进行 去重

limit  也是用在前面的提条件之后

是对于数据的展示条数的限制

一.查询顺序

  1.1.语法执行顺序

1.1.语法执行顺序
# # 1.查询id大于等于3小于等于6的数据
    select * from emp where id >=3 and id <= 6;
    # 先后顺序
    from    >>>从那张表 数据的来源
    where   >>>的限制条件
    selecct >>>最终展示我们想要的数据

  1.2.where约束条件

# 2.查询薪资是20000或者18000或者17000的数据

    # 这里有两种方法
    select  * from emp where salary=20000 or salary=18000 or salary=17000;

    # 可以用in 方法

    select * from emp where salary in (20000,18000,17000);

mysql> select * from emp where salary in (20000,18000,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.查询员工姓名中包含o字母的员工姓名和薪资

# 模糊匹配 关键字like
    select name,salary from  emp  where name like ‘%o%‘;

    # 细心点 匹配所有带o名字的字母

  # 4.查询员工姓名是由四个字符组成的员工姓名与其薪资

select name,salary from emp where name like ‘____‘;

    # % 是匹配所有的
    # _ 一个下划线匹配一个 注意事项:_ 引号内

    方法二#char_length
    select name,salary from emp where char_length(name)=4;

  # 5.查询id小于3或者大于6的数据 集体数据

select * from emp where not id >=3 or id <=6;
select * from emp where not id <3 or id >6;

1.2.where约束条件

  #6.查询薪资不在20000,18000,17000范围的数据

select * from emp where salary not in (20000,18000,17000);

select name,salary from emp where salary not in (20000,18000,17000);

  # 7.查询岗位描述为空的员工名与岗位名

     select name,post from emp where post_comment is NULL;

    # 查询SQL语句中为空的信息字段不能post_comment=Null 只能用is=Null;

3.group by

  # 1.按部门分组  这里没有where 限制条件

select post from emp group by post;

mysql> select post from emp group by post; # by 后面根要按照什么分组
+-----------------------------+
| post |
+-----------------------------+
| operation |
| sale |
| teacher |
| 张江第一帅形象代言 |
+-----------------------------+

  # 2.获取每个部门 的 最高工资   #  先分组 再用聚合函数 sum() avg() max() min()

from  >>>  那张表 表名
    where >>> 第一层大的限制条件
    group by >>> 进行分组后是最小的单位 不能直接获取下面的具体值 可以group_concat()

    select  >>> 展示最高工资 这是进行最后展示的操作

    # 这里没有where 限制条件(全局)
    select post, max(salary) from emp group by 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 |
    +-----------------------------+-------------+

  # 3.查询分组之后的部门名称和每个部门下所有的员工姓名

# 一般按照分组之后 组就是最小的单位 但是可以 分组的group_concat()方法获取
select post,group_concat(name),count(id) from emp group by post;
# 展示是按照你的写的顺序添加的字段 只要有结果就会一一显示

  # 4.补充concat(不分组时用)拼接字符串达到更好的显示效果 as语法使用

# concat 没有分组的时候就是类似与字符串的拼接的功能 已达到整齐的显示结果

    如 : 显示名字和分组
    select concat("姓名:",name) as ‘名字‘,concat("工资:", salary)as ‘工资‘ from emp group by post having avg(salary)>2000;

        +---------------+-------------------+
    | 名字          | 工资              |
    +---------------+-------------------+
    | 姓名:张野     | 工资:10000.13     |
    | 姓名:歪歪     | 工资:3000.13      |
    | 姓名:egon     | 工资:1000000.31   |
    | 姓名:jason    | 工资:7300.33      |
    +---------------+-------------------+
    4 rows in set (0.00 sec)

    # 注意:这里的concat作用是拼接字符串 还可以将表头 一关键字as 起别名
    # 注意2:还就就是要分几个表头就 用几个contcat 进行分列 展示 concat 进行字符串的拼接

  5.# 查询四则运算及聚合函数 sum avg max min

# 查询每个人的年薪
    # 重表中 获取name 和 salary* 12 就是年薪了
    select name,salary*12 from emp;
    mysql> select name,salary*12 from emp;
    +-----------+-------------+
    | name      | salary*12   |
    +-----------+-------------+
    | jason     |    87603.96 |
    | egon      | 12000003.72 |
    | kevin     |    99600.00 |
    | tank      |    42000.00 |
    +-----------+-------------+
     还有很多就不一一列举了

练习:

  

    # 刚开始查询表,一定要按照最基本的步骤,先确定是哪张表,再确定查这张表也没有限制条件,再确定是否需要分类,最后再确定需要什么字段对应的信息

    1. 查询岗位名以及岗位包含的所有员工名字
    # 岗位为post group_concat(name):岗位里包含所有人的名字
     select post,group_concat(name) from emp group by  post;

    2. 查询岗位名以及各岗位内包含的员工个数
    select post, count(id) from emp group by post;

    3. 查询公司内男员工和女员工的个数
    select sex,count(id) from emp group by sex;
        +--------+-----------+
    | sex    | count(id) |
    +--------+-----------+
    | male   |        10 |
    | female |         8 |
    +--------+-----------+
    2 rows in set (0.00 sec)

    4. 查询岗位名以及各岗位的平均薪资

    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)

    5. 查询岗位名以及各岗位的最高薪资

    select name,post,max(salary) from emp group by post;
    # m名字可以自己家帮我们展示每个部分的最高工资的人

    6. 查询岗位名以及各岗位的最低薪资
    select post,min(salary)from emp group by post;
    # 注意分组之后只能拿到分组的这个组作为最小的单位 其他信息没有办法拿到
    # 可以通过group_concat()获取name的信息

    7. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
    select sex, avg(salary) from emp group by sex;

    mysql> select sex, avg(salary) from emp group by sex;

    mysql> select sex, avg(salary) from emp group by sex;

    +--------+---------------+
    | sex    | avg(salary)   |
    +--------+---------------+
    | male   | 110920.077000 |
    | female |   7250.183750 |
    +--------+---------------+
    2 rows in set (0.00 sec)

4.having

from

where

group by 必须在where 之后 才能使用

having 必须是和group by 一起使用 而且必须在分组之后

select

例如:

  1、统计各部门年龄在30岁以上的员工平均工资,并且保留平均工资大于10000的部门

    select post,avg(salary) from emp  where age >=30 group by  post having avg(salary)>10000;

5.distinct

# 去重对于 是在select 之后 执行 distinct

select distinct age from emp ; 将重复的年纪去除

6.order by: 排序  展示

列如:

  

#先按照age降序排,在年轻相同的情况下再按照薪资升序
        select name,age,salary from  emp order by age ,salary desc;
        select * from  emp order by age ,salary desc;
        # asc 是默认升序
        # desc  降序排列
        
    # 统计各部门年龄在10岁以上的员工平均工资,并且保留平均工资大于1000的部门,
        然后对平均工资进行排序
        select post ,avg(salary) from emp where age >30 group by post having avg(salary)>1000
        order by avg(salary) desc;
        +---------+---------------+
        | post    | avg(salary)   |
        +---------+---------------+
        | teacher | 255450.077500 |
        | sale    |   2500.240000 |
        +---------+---------------+
        

7.limit

  # 限制查询的条数

select id,name,post,salary from emp limit 0,5; >0 所以重第一条开始

        # 展示=内容我们可以自己设定字段
        # 0信息是信息的起始位 表示从1 开始 往后读取5条信息

        # select * from emp limit 5,10; 不包含5 从第六条开始

8.正则

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

# 以 j 开始 . 是除换行服 外的任意字符 * 是别 (n|y)$ n或结尾

二.多表查询
表创建

  select * from emp,dep;


# 建表
create table dep(id int ,name varchar(20));

# 建emp表
create table emp(id int primary key auto_increment,
name varchar(28),
sex enum("male","female") not null default "male",
age int ,
dep_id int );


#  插入值dep

insert into dep values
(200,‘技术‘),
(201,‘人力资源‘),
(202,‘销售‘),
(203,‘运营‘);

# emp的值

insert into emp(name,sex,age,dep_id) values
(‘jason‘,‘male‘,18,200),
(‘egon‘,‘female‘,48,201),
(‘kevin‘,‘male‘,38,201),
(‘nick‘,‘female‘,28,202),
(‘owen‘,‘male‘,18,200),
(‘jerry‘,‘female‘,18,204)
;

# 分表为了方便管理
# 合表为方便查询

1.表查询
# 同时查两张表
select * from emp,dep;
# 左表的一条记录与右表所有几率都对应一遍 >>> 笛卡尔积
# 缺点:
所有的表都对应了一遍,很显然是不合理的,现在我们需要做的就是找出合理多核数据

  #1. 查询员工及所在的部门信息
  select * from emp,dep where emp.dep_id = dep_id;

# 查询部门为技术部的员工及部门信息
        mysql> select * from emp;
            +----+-------+--------+------+--------+
            | id | name  | sex    | age  | dep_id |
            +----+-------+--------+------+--------+
            |  1 | jason | male   |   18 |    200 |
            |  2 | egon  | female |   48 |    201 |
            |  3 | kevin | male   |   38 |    201 |
            |  4 | nick  | female |   28 |    202 |
            |  5 | owen  | male   |   18 |    200 |
            |  6 | jerry | female |   18 |    204 |
            +----+-------+--------+------+--------+
        mysql> select * from dep;
            +------+--------------+
            | id   | name         |
            +------+--------------+
            |  200 | 技术         |
            |  201 | 人力资源     |
            |  202 | 销售         |
            |  203 | 运营         |
            +------+--------------+

  2.# 需求 查询jason的部门

# 思路从emp员工中可以查到 jason dep_id

# 再通过jason 的dep_id 的 对应哪个部门

select * from emp where emp.dep_id=dep.id and dep.name = ‘技术‘;

# Unknown column ‘dep.id‘ in ‘where clause‘

  # 系统内部会"dep_id" 不存在改字段  >>> 所以我们需要用到内连接

  (1)# 1.内链接 inner join  只取两张表有对应关系的记录

select * from emp inner join dep on emp.dep_id =dep.id where dep.name=‘技术‘;  查询所有能id he技术能关联的内表

select * from emp inner join dep on emp.dep_id =dep.id where dep.name=‘技术‘and emp.name=‘jason‘;

select * from emp inner join dep on emp.dep_id =dep.id where dep.name=‘技术‘and emp.name=‘jason‘;
+----+-------+------+------+--------+------+--------+
| id | name | sex | age | dep_id | id | name |
+----+-------+------+------+--------+------+--------+
| 1 | jason | male | 18 | 200 | 200 | 技术 |
+----+-------+------+------+--------+------+--------+
1 row in set (0.00 sec)

  (2)# 2.左lete join 左链接:在内连接的基础上保留左表没有的对应关系的记录

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 | jason | male   |   18 |    200 |  200 | 技术         |
        |  5 | owen  | male   |   18 |    200 |  200 | 技术         |
        |  2 | egon  | female |   48 |    201 |  201 | 人力资源     |
        |  3 | kevin | male   |   38 |    201 |  201 | 人力资源     |
        |  4 | nick  | female |   28 |    202 |  202 | 销售         |
        |  6 | jerry | female |   18 |    204 | NULL | NULL         |
        +----+-------+--------+------+--------+------+--------------+

  (3)# 3.右链接: 在内连接的基础上保留左表没有对应关系的记录

    select * from emp rigth 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 | jason | male   |   18 |    200 |  200 | 技术         |
        |  5 | owen  | male   |   18 |    200 |  200 | 技术         |
        |  2 | egon  | female |   48 |    201 |  201 | 人力资源     |
        |  3 | kevin | male   |   38 |    201 |  201 | 人力资源     |
        |  4 | nick  | female |   28 |    202 |  202 | 销售         |
        |  6 | jerry | female |   18 |    204 | NULL | NULL         |
        +----+-------+--------+------+--------+------+--------------+

  (4)# 4.全连接:在内连接的基础上保留 左 右 表中没有的对应关系的记录

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 | jason | male   |   18 |    200 |  200 | 技术         |
        |    5 | owen  | male   |   18 |    200 |  200 | 技术         |
        |    2 | egon  | female |   48 |    201 |  201 | 人力资源     |
        |    3 | kevin | male   |   38 |    201 |  201 | 人力资源     |
        |    4 | nick  | female |   28 |    202 |  202 | 销售         |
        |    6 | jerry | female |   18 |    204 | NULL | NULL         |
        | NULL | NULL  | NULL   | NULL |   NULL |  203 | 运营         |
        +------+-------+--------+------+--------+------+--------------+

三.子查询

  # 就是一个查询=语句用括号括起来当作另一个查询语句的条件去用
  如:

  # 1.查询部门是技术或者人力资源的员工信息

先获取技术部和人力资源部的id号,再去员工表里面根据前面的id筛选出符合要求的员工信息
"""
select * from emp where dep_id in (select id from dep where name = "技术" or name = "人力资源");

  # 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
;

"""
记住一个规律,表的查询结果可以作为其他表的查询条件,也可以通过其别名的方式把它作为一张虚拟表去跟其他表做关联查询
"""

原文地址:https://www.cnblogs.com/mofujin/p/11392105.html

时间: 2024-11-11 01:07:48

MySQL之表查询的相关文章

python3 mysql 多表查询

python3 mysql 多表查询 一.准备表 创建二张表: company.employee company.department #建表 create table department( id int, name varchar(20) ); create table employee( id int primary key auto_increment, name varchar(20), sex enum('male','female') not null default 'male'

MySQL多表查询回顾

----------------------siwuxie095 MySQL 多表查询回顾 以客户和联系人为例(一对多) 1.内连接 /*内连接写法一*/ select * from t_customer c,t_linkman l where c.cid=l.clid /*内连接写法二(inner 可以省略不写)*/ select * from t_customer c inner join t_linkman l on c.cid=l.clid 2.左外连接 /*左外连接(outer 可以省

mysql多表查询方法(left join(左连接),right join (右连接),inner join (内连接)的区别)

表A记录如下:  aID aNum  1 a20050111  2 a20050112  3 a20050113  4 a20050114  5 a20050115  表B记录如下:  bID bName  1 2006032401  2 2006032402  3 2006032403  4 2006032404  8 2006032408  创建这两个表SQL语句如下:  CREATE TABLE a  aID int( 1 ) AUTO_INCREMENT PRIMARY KEY ,  a

MySQL information_schema表查询导致内存暴涨

case:下面的一条sql语句,导致mysql实例内存暴涨: select * from tables where table_name not in(select table_name from partitions group by table_name having count(*)>1 ); mysql 5.5, 1w+的innodb表. 下面看下调查的结果: 1.  sql的执行情况以及内存分配:   step1: 构造information_schema.tables临时表 1.1 

MYSQL 连表查询及别名用法

MYSQL连表查询是两个表之间的查询或者更多表之间查询,通过外键的方式查询所有的数据,在查询过程中产生字段的重复,为了区分这种情况数据库设计别名,有的表很长,也可以用别名. 1,连表查询 INNER JOIN ,LEFT JOIN,RIGHT JOIN INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录.LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录.RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表

4 - MySQL:多表查询

MySQL:多表查询 一,介绍 本节主题 多表连接查询 复合条件连接查询 子查询 准备工作 #建表 create table department( id int, name varchar(20) ); create table employee( id int primary key auto_increment, name varchar(20), sex enum('male','female') not null default 'male', age int, dep_id int

记一次mysql多表查询(left jion)优化案例

一次mysql多表查询(left jion)优化案例 在新上线的供需模块中,发现某一个查询按钮点击后,出不来结果,找到该按钮对应sql手动执行,发现需要20-30秒才能出结果,所以服务端程序判断超时,故先不显示结果 以下是对这条查询的优化记录 1 数据库配置 数据库配置:4C8G 主表数据:3W+ 2 sql语句 提取sql语句,简化如下 SELECT taba.id, taba.title, taba.type, taba.end_time, tabb.username, tabc.orgna

python开发mysql:单表查询&amp;多表查询

一 单表查询,以下是表内容 1 一 having 过滤 2 1.1 having和where 3 select * from emp where id > 15; 4 解析过程;from > where 找到数据 > 分组(没有默认一个组)> select 打印 where是出结果之前 5 select * from emp having id > 15; 6 解析过程;from > where 找到数据(没有约束条件,就是整个表)) > 分组(没有默认一个组)&

mysql联表查询,使用phpStudy自带的

一.内联结.外联结.左联结.右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结.2.外联结:分为外左联结和外右联结.左联结A.B表的意思就是将表A中的全部记录和表B中联结的字段与表A的联结字段符合联结条件的那些记录形成的记录集的联结,这里注意的是最后出来的记录集会包括表A的全部记录.右联结A.B表的结果和左联结B.A的结果是一样的,最后出来的记录集会包括表B的全部记录.具体如下: Select l

MYSQL多表查询事例

1.order by 排序 mysql> select * from xin order by id; +------+----------+ | id   | name     | +------+----------+ |    1 | lilie    | |    2 | tianjin  | |    3 | shanghai | +------+----------+ 2.按照升序排列 mysql> select * from xin order by id asc; +-----