MySQL - 单表查询 &多表查询

 

目录

单表查询

- 语法

- 关键字的执行优先级

- 简单查询

- WHERE语句

- ORDER BY 查询后排序返回

- GROUP BY  :根据一个列或多个列进行分组

- DISTINCT:去重,执行顺序是在having过滤后执行去重

- LIMIT :限制查询的记录数

 - 使用正则表达式查询

- 聚合函数:聚合的是组的内容,若是没有分组,则默认一组

多表查询

 - 表的外连接语法

- 外连接 - LEFT JOIN (左连接) :获取左表所有记录,即右表没有对应匹配的记录

- 外连接 - RIGHT JOIN(右连接):获取右表所有记录,即左表没有对应匹配的记录

- INNER JOIN(内连接 或 等值连接):获取两个表中字段匹配关系的记录       

- FULL JOIN(全外连接):显示左右俩表全部记录

 - 交叉连接:不使用任何匹配条件。生产笛卡尔积

- 符合条件的连接查询

- 子查询

带IN关键字的子查询

带比较运算符的子查询

带EXISTS关键字的子查询


单表查询

- 语法

SELECT 字段1,字段2... FROM 表名
                  WHERE 条件
                  GROUP BY field
                  HAVING 筛选
                  ORDER BY field
                  LIMIT 限制条数

- 关键字的执行优先级

  1. from :找到表
  2. where:拿到约束条件,去表中取记录
  3. group by:取出记录进行分组,若没有group by关键字,则整体作为一组
  4. having:将分组结果进行过滤
  5. select:查找
  6. distinct:去重
  7. order by:将结果按条件进行排序
  8. limit:限制结果的显示条数

- 简单查询

SELECT id,name,sex,age,hire_date,post,post_comment,salary,office,depart_id 
FROM employee;
 
SELECT * FROM employee;
 
SELECT name,salary FROM employee;

- WHERE语句

SELECT field1, field2,...fieldN 
       FROM table_name1, table_name2...
       [WHERE condition1 [AND [OR]] condition2.....

例如: select * from tb where 字段名 = ‘指定名字’

where 约束:

  1. 比较运算符,如下图:
  2. between 1 and 10  ------1-10之间
  3. in(8,,3,4) -------是8或3或4
  4. and,or,not ----------逻辑运算符
  5. %,_用法:

    ‘%a’ : 以a结尾的数据

    'a%' : 以a开头的数据

    '%a%' : 含a的数据

    '_a_' : 三位且中间字母为a的

    '_a' : 两位且结尾字母是a的

    'a_' : 两位且开头字母是a的

  6. WHERE LIKE:获取类正则的使用效果

  7. SELECT field1, field2,...fieldN 
    FROM table_name
    WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
    

    例:SELECT * from runoob_tbl WHERE runoob_author LIKE '%COM';
    - 可以在where子句中指定任何条件。
    - 可以使用like子句代替等号=。
    - like通常与%一同使用,类似于一个元字符的搜索。
    - 可以使用 and 或者 or 指定一个或多个条件。
    - 可以在 delete 或 update 命令中使用 where…like 子句来指定条件

- ORDER BY 查询后排序返回

SELECT field1, field2,...fieldN table_name1, table_name2...
ORDER BY field1, [field2...] [ASC [DESC]]

例:SELECT * from runoob_tbl ORDER BY submission_date ASC;

  • 你可以使用任何字段来作为排序的条件,从而返回排序后的查询结果。
  • 你可以设定多个字段来排序。
  • 你可以使用 ASC(升序) 或 DESC(降序) 来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。
  • 你可以添加 WHERE...LIKE 子句来设置条件。

- GROUP BY  :根据一个列或多个列进行分组

SELECT column_name, function(column_name)
    FROM table_name
    WHERE column_name operator value
    GROUP BY column_name;

例:SELECT 字段1, SUM(字段2) as 新字段2 FROM  table1 GROUP BY 字段1 WITH ROLLUP;

注:
  #设置sql_mode为only_full_group_by,意味着以后但凡分组,只能取到分组的依据
    mysql> set global sql_mode="strict_trans_tables,only_full_group_by";

   #分组之后的聚合操作:

    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(id) from emp group by post;   #每个部门的员工数

    #group_concat(分组之后用,取出字段,或者对指定字段执行拼接操作)

select post,group_concat(name) from emp group by post;
select post,group_concat(name,"_SB") from emp group by post;
select post,group_concat(name,": ",salary) from emp group by post;
select post,group_concat(salary) from emp group by post;

   # 补充concat(不分组时用,取出字段并对指定字段进行拼接操作。用as将字段起别名)

    select name as 姓名,salary as 薪资 from emp;
    select concat("NAME: ",name) as 姓名,concat("SAL: ",salary) as 薪资 from emp;

  # concat_ws(不分组时使用,多次使用相同拼接符缩写)

select concat_ws(":",name,age,sex,post)as info from emp;

'''
concat_ws("分隔符",字段名1,字段名2,...) as 别名

数据结果:
    name1:14:female:operation
    name2:15:female:operation
.......

'''

   

 # 补充as语法(起别名)

    mysql> select emp.id,emp.name from emp as t1; # 报错
    mysql> select t1.id,t1.name from emp as t1;

   # 查询四则运算(加减乘除)

    select name,salary*12 as annual_salary from emp;

'''可以省略as 上下两句结果相同'''
    select name,salary*12 annual_salary from emp;

- HAVING :在分组后的过滤

having & where:

  • !!!执行优先级从高到低:where > group by > having
  • 1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。
  • 2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数

例:select post,group_concat(name) from emp group by post having avg(salary) > 10000;

- DISTINCT:去重,执行顺序是在having过滤后执行去重

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

- LIMIT :限制查询的记录数

示例:(分页显示)
    SELECT * FROM employee ORDER BY salary DESC LIMIT 3;
              #默认初始位置为0 (0,3]
    
    SELECT * FROM employee ORDER BY salary DESC LIMIT 0,5; 
              #从第0开始,即先查询出第1条,然后包含这一条在内往后查5条((0,5],取后不取前)
 
    SELECT * FROM employee ORDER BY salary DESC LIMIT 5,5; 
              #从第5开始,即先查询出第6条,然后包含这一条在内往后查5条

 - REGEXP(正则表达式) 查询

SELECT * FROM employee WHERE name REGEXP '^ale';
 
SELECT * FROM employee WHERE name REGEXP 'on$';
 
SELECT * FROM employee WHERE name REGEXP 'm{2}';
 
 
小结:对字符串匹配的方式
WHERE name = 'name';
WHERE name LIKE 'yua%';
WHERE name REGEXP 'on$';

- 聚合函数:聚合的是组的内容,若是没有分组,则默认一组

示例:
    SELECT COUNT(*) FROM employee;
    SELECT COUNT(*) FROM employee WHERE depart_id=1;
    SELECT MAX(salary) FROM employee;
    SELECT MIN(salary) FROM employee;
    SELECT AVG(salary) FROM employee;
    SELECT SUM(salary) FROM employee;
    SELECT SUM(salary) FROM employee WHERE depart_id=3;

多表查询

 - 表的外连接语法

SELECT 字段列表
    FROM 表1 INNER|LEFT|RIGHT JOIN 表2
    ON 表1.字段 = 表2.字段;

- 外连接 - LEFT JOIN (左连接) :获取左表所有记录,即右表没有对应匹配的记录

- 外连接 - RIGHT JOIN(右连接):获取右表所有记录,即左表没有对应匹配的记录

- INNER JOIN(内连接 或 等值连接):获取两个表中字段匹配关系的记录       

- FULL JOIN(全外连接):显示左右俩表全部记录

注:

  1. mysql不支持全外连接,但是mysql可以间接实现全外连接
  2. 注意 union与union all的区别:union会去掉相同的纪录
select * from employee left join department on employee.dep_id = department.id 
union
select * from employee right join department on employee.dep_id = department.id;

 - 交叉连接:不使用任何匹配条件。生产笛卡尔积

select * from employee,department;

- 符合条件的连接查询

  • 内连接方式查询,并设置where筛选
select employee.name,department.name from employee inner join department
    on employee.dep_id = department.id
    where age > 25;
  • 内连接方式查询,并设置字段排序方式显示
select employee.id,employee.name,employee.age,department.name from employee,department
    where employee.dep_id = department.id
    and age > 25
    order by age asc;

- 子查询

#1:子查询是将一个查询语句嵌套在另一个查询语句中。
#2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。
#3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
#4:还可以包含比较运算符:= 、 !=、> 、<等
  1. 带IN关键字的子查询
     

    #查询平均年龄在25岁以上的部门名
    select id,name from department
        where id in 
            (select dep_id from employee group by dep_id having avg(age) > 25);
     
    #查看技术部员工姓名
    select name from employee
        where dep_id in 
            (select id from department where name='技术');
     
    #查看不足1人的部门名(子查询得到的是有人的部门id)
    select name from department where id not in (select distinct dep_id from employee);
    
  2. 带比较运算符的子查询
     

    #比较运算符:=、!=、>、>=、<、<=、<>
    #查询大于所有人平均年龄的员工名与年龄
    mysql> select name,age from emp where age > (select avg(age) from emp);
    +---------+------+
    | name | age |
    +---------+------+
    | name1 | 48 |
    | name2 | 38 |
    +---------+------+
    2 rows in set (0.00 sec)
     
     
    #查询大于部门内平均年龄的员工名、年龄
    select t1.name,t1.age from emp t1
    inner join 
    (select dep_id,avg(age) avg_age from emp group by dep_id) t2
    on t1.dep_id = t2.dep_id
    where t1.age > t2.avg_age; 
    
  3. 带EXISTS关键字的子查询
     

    #比较运算符:=、!=、>、>=、<、<=、<>
    #查询大于所有人平均年龄的员工名与年龄
    mysql> select name,age from emp where age > (select avg(age) from emp);
    +---------+------+
    | name | age |
    +---------+------+
    | name1 | 48 |
    | name2 | 38 |
    +---------+------+
    2 rows in set (0.00 sec)
     
     
    #查询大于部门内平均年龄的员工名、年龄
    select t1.name,t1.age from emp t1
    inner join 
    (select dep_id,avg(age) avg_age from emp group by dep_id) t2
    on t1.dep_id = t2.dep_id
    where t1.age > t2.avg_age; 
    

猜你喜欢

转载自blog.csdn.net/qq_33961117/article/details/82631384