• (五)连接查询(SQL99标准)、子查询、分页查询、联合查询


    一、连接查询(SQL99标准)

    1、含义:当要查询的数据来自多张表时要使用连接查询

    2、语法:

    select 查询列表
    from 表1 别名 
    【连接类型】 join 表2 别名 
    on 连接条件
    【where 筛选条件】
    【group by 分组】
    【having 筛选条件】
    【order by 排序列表】

    注意:SQL99标准支持以下连接方式:

    #1内连接
    
    #2外连接:左外、右外、全外连接
    
    #3交叉连接(很少用到)

    3、内连接:

    案例一:查询部门个数>3的城市名和部门个数(分组函数+分组查询)

    上图可以看出两个表之间的关系

    SELECT COUNT(*),l.`city`
    FROM departments d
    INNER JOIN locations l ON d.`location_id`=l.`location_id`
    GROUP BY l.`city`
    HAVING COUNT(*)>3;

    案例二:查询员工名、部门名、工种名,并按部门名降序(添加三表连接)

    SELECT last_name,department_name,job_title
    FROM employees e
    INNER JOIN departments d ON e.`department_id`=d.`department_id`
    INNER JOIN jobs j ON e.`job_id`=j.`job_id`
    ORDER BY d.`department_name` DESC;

    注意:根据上面两个案例可以看出内连接时连接类型使用INNER(可省略)

    4、外连接(左外、右外连接)

    ①用到的库信息:

    ②区分左、右外连接:

    ③左外连接:

    案例:查询男朋友不在男生表中的女神名

    SELECT b.`name`
    FROM beauty b
    LEFT JOIN boys bo ON b.`boyfriend_id`=bo.`id`;

    注意:左外连接类型使用LEFT  OUTER ,其中OUTER可以省略

    ④右外连接:

    案例:查询男朋友不在男生表中的女神名

    SELECT b.`name`
    FROM boys bo
    RIGHT JOIN beauty b ON bo.`id`=b.`boyfriend_id`;

    注意:右外连接类型使用RIGHT  OUTER ,其中OUTER可以省略

    ⑤区分内外连接:

          

    二、子查询

    1、含义:SQL语句中嵌套其它完整的SQL语句

    2、分类:

    select后: 标量子查询(结果集只有一行一列)
    
    from后:表子查询(多行多列)
    
    where或having后:标量子查询()、列子查询(一列多行)、行子查询(一行多列)
    
    exists后面:相关子查询、表子查询

    注意:

    ①子查询要放在小括号中,且子查询不需要添加分号

    ②标量子查询:一般搭配单行操作符使用(> < >= <= = <>)

    ③列子查询:一般搭配多行操作符使用(in、any/some、all)

    3、WHERE或HAVING后面的子查询:

    ①标量子查询:

    案例1:谁的工资比 Abel 高? (子查询)

    step1:查询Abel的工资

    USE myemployees;
    SELECT e.salary Abel的工资
    FROM employees e
    WHERE e.last_name='Abel';

    step2:将step1的结果当作子查询嵌套在step中

    SELECT last_name
    FROM employees e
    WHERE e.`salary`>(
    	SELECT e.salary Abel的工资
    	FROM employees e
    	WHERE e.last_name='Abel'
    );

    运行结果:

    案例2:返回job_id与141号员工相同,salary比143号员工多的员工 姓名,job_id(多个子查询)

    step1:查询141号员工的job_id

    SELECT e.job_id
    FROM employees e
    WHERE e.`employee_id`=141;

    step2:143号员工的工资

    SELECT e.salary
    FROM employees e
    WHERE e.`employee_id`=143;

    step3:将step1、step2的结果嵌套到step3中

    SELECT e.last_name,e.job_id
    FROM employees e
    WHERE e.`job_id`=(
    	SELECT e.job_id
    	FROM employees e
    	WHERE e.`employee_id`=141
    )AND e.salary > (
    	SELECT e.salary
    	FROM employees e
    	WHERE e.`employee_id`=143	
    );

    案例3:查询最低工资大于50号部门最低工资的部门id和其最低工资(分组查询+HAVING后子查询)

    SELECT department_id,MIN(salary)
    FROM employees
    GROUP BY department_id
    HAVING MIN(salary)>( #筛选的时候注意是where还是having
    	SELECT MIN(salary)
    	FROM employees
    	WHERE department_id=50
    );

    ②列子查询:

    案例:返回location_id是1400或1700的部门中的所有员工姓名

    SELECT e.last_name
    FROM employees e
    WHERE e.`department_id` IN(
    	SELECT d.department_id
    	FROM departments d
    	WHERE d.`location_id` IN(1400,1700)
    );

    注意:IN 等价于=ANY ( ) , NOT IN 等价于<> ALL( ) 

    ③行子查询:

    案例:查询员工编号最小并且工资最高的员工信息

    SELECT * 
    FROM employees
    WHERE (employee_id,salary)=(
    	SELECT MIN(employee_id),MAX(salary)
    	FROM employees
    );

    SELECT *
    FROM employees
    WHERE employee_id=(
    	SELECT MIN(employee_id)
    	FROM employees
    )AND salary=(
    	SELECT MAX(salary)
    	FROM employees
    );

    4、FROM后面的子查询

    含义:FROM后面跟的是表,所以子查询的结果也应该是一张表。

    注意:FROM后面的子查询必须要起别名

    案例:查询每个部门的平均工资的工资等级

    step1:查询每个 部门的平均工资和部门编号

    SELECT AVG(salary),department_id
    FROM employees
    GROUP BY department_id;

    运行结果:

    注意:运行结果是一张表

    step2:根据step1得出的表,判断工资等级

    SELECT  ag_dep.*,g.`grade_level`
    FROM (
    	SELECT AVG(salary) ag,department_id
    	FROM employees
    	GROUP BY department_id
    ) ag_dep
    INNER JOIN job_grades g
    ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;

    5、SELECT后面子查询(仅支持标量子查询)

    案例:查询每个部门的员工个数 

    SELECT d.*,(
    	SELECT COUNT(*)
    	FROM employees e
    	WHERE d.`department_id`=e.department_id
    )个数
    FROM departments d;

    6、EXITS后面的子查询

    语法:(返回值仅为1/0,当括号中表不为空时返回1,否则返回0)

    SELECT EXISTS(SELECT * FROM employees);

    案例:查询有员工的部门名

    SELECT department_name
    FROM departments d
    WHERE EXISTS(
    	SELECT *
    	FROM employees e
    	WHERE e.`department_id`=d.`department_id`
    );

    三、分页查询

    1、含义:从一张表中选出连续几行数据要用到分页查询。

    2、语法:

    SELECT 查询列表
    FROM 表
    【JOIN TYPE JOIN 表2
    ON 连接条件
    WHERE 筛选条件
    GROUP BY 分组字段
    HAVING 分组后的筛选
    ORDER BY 排序的字段】
    LIMIT 【OFFSET,】size;
    

    注意:OFFESET:起始索引(默认从0开始) SIZE:总行数

    案例1:有奖金的员工信息,显示工资较高的前10名

    step1:降序排列有奖金的员工信息

    SELECT e.*
    FROM employees e
    WHERE e.`commission_pct` IS NOT NULL
    ORDER BY e.`salary` DESC;

    step2:将员工信息的前十条筛选出来

    SELECT e.*
    FROM employees e
    WHERE e.`commission_pct` IS NOT NULL
    ORDER BY e.`salary` DESC
    LIMIT 0,10;

    案例2:已知页数page和每页的行数size,写出通式

    SELECT 查询列表
    ​FROM 表
    ​LIMIT (page-1)*size,size;

    四、联合查询

    1、优点:当多张表之间没有连接条件时,使用UNION(联合查询)很方便。

    2、语法:

    查询语句1
    UNION
    查询语句2
    UNION
    ……

    注意:

    ①要求多条查询语句的查询列数一致且每条查询语句都要完整(可单独执行),非最后一条查询条件不需要添加分号

    最终显示的字段名称是第一条查询条件中所查询的内容,要保证所有查询语句所查询的内容一致且数目相等

    UNION查询默认去重,可使用UNION ALL来避免去重

    案例1:查询部门编号>90或邮箱包含a的员工信息

    SELECT * FROM employees  WHERE email LIKE '%a%'
    UNION
    SELECT * FROM employees  WHERE department_id>90;

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    复习整理,如有错误请指出。

  • 相关阅读:
    【闲暇研究】某问道,问问,道道宠物素材整理
    小米手机刷机,官方教程。
    【闲暇研究】某问道,每日极品道具体验礼包。
    【闲暇研究】某问道,悟道只能用银元宝。
    Windows Server 2016从Evaluation评估版转换成正式版
    【闲暇研究】某问道,仙元、道具合成的修改,与参考文件。
    关于小米手机安装APP总是提示“与已安装应用签名不同”的问题
    WebStorm的快捷键,技巧
    Webstorm(常见配置+Emmet简单语法)
    05-方法重写
  • 原文地址:https://www.cnblogs.com/ldu-xingjiahui/p/12594040.html
Copyright © 2020-2023  润新知