美文网首页
sql笔记 P49-86

sql笔记 P49-86

作者: kevinXiao | 来源:发表于2021-09-07 20:27 被阅读0次

    #五、流程控制函数

    #1. if函数:if else 的函数

    SELECT IF(10 > 5, '大', '小')

    #2.case函数的使用一:switch case 的效果

    java中

    switch(变量或表达式){

        case 常量1:语句1;break;

       ...

        default:语句n; break

    }

    mysql中

    case 要判断的字段或表达式

    when 常量1 then 要显示的值1或者语句1;

    when 常量2 then 要显示的值2或者语句2;

    ...

    else 要显示的值n或语句n;

    end

    #案例:查询员工的工资,要求

    部门号=30,显示的工资为1.1倍

    部门号=40,显示的工资为1.2倍

    部门号=50,显示的工资为1.3倍

    select salary 原始工资, department_id,

    CASE department_id

    when 30 then salary*1.1

    when 40 then salary*1.2

    when 50 then salary*1.3

    else salary

    end AS 新工资

    FROM employees;

    #3.case 函数的使用二:类似于多重if

    java中

    /*

    if(条件1){

        语句1;

    }else if(条件2) {

         语句2;

    }...

    else{

        语句n;

    }

    */

    mysql中:

    case 

    when 条件1 then 要显示的值1或语句1

    when 条件2 then 要显示的值2或语句2

    ...

    else 条件n then 要显示的值n或语句n

    #案例:查询员工的工资情况

    如果工资>20000,显示A级别

    如果工资>15000,显示B级别

    如果工资>10000,显示C级别

    否则,显示D级别

    select salary,

    CASE

    WHEN salary > 20000 then 'A'

    WHEN salary > 15000 then 'B'

    WHEN salary > 10000 then 'C'

    ELSE 'D'

    END AS 工资级别

    FROM employees

    #二、分组函数

    /*

    功能:用作统计使用,又称为聚合函数或统计函数或组函数

    分类:

    sum 求和、avg 平均、max 最大值、min 最小值、count 计算个数

    特点:

    1、sum、avg一般用于处理数值型

        max、min、count 可以处理任何类型

    2、以上分组函数都忽略null值

    3、可以和distinct搭配实现去重的运算

    4、count函数的单独介绍

        一般使用count(*)用作统计行数

    5、和分组函数一同查询的字段要求是group by 后的字段

    */

    #1、简单使用

    select sum(salary) from employees

    select count(salary) from employees

    select sum(salary) 和 , count(salary) 个数 from employees

    #2、参数支持哪类类型

    #3、是否忽略null

    select sum(commission_pct), avg(comission_pct), sum(commission_pct)/35, sum(commission_pct)/107 from employees

    #4、和distinct搭配

    select sum(distinct salary), sum(salary ) from employees

    #5、count函数的详细介绍

    select count(salary) from emplyoees

    select count(*) from emplyoees   //统计个数

    select count(1) from emplyoees   有多少行就有多少个1

    效率:

    innodb存储引擎下,count(*)和count(1)的效率差不多,比count(字段)要高一些

    #6、和分组函数一同查询的子弹有限制

    select avg(salary), employee_id from employees;

    #进阶5:分组查询

    /*

    select column, group_function(column)

    from table

    [where condition]

    [group by group_by_expression]

    [order by column]  

    select 分组函数,列(要求出现在group by的后面)

    from 表

    【where 筛选条件】

    【group by 分组的列表】

    【order by 子句】

    注意:

        查询列表必须特殊,要求是分组函数和group by后出现的字段

    特点:

        1、分组查询中的筛选条件分类两类

                                            数据源                                位置                                                    关键字

        分组前筛选                原始表                                group by 字句的前面                        where

        分组后筛选                分组后的结果集                group by字句的后面                        having

        1.分组函数条件肯定是放在having子句中

        2.能用分组前筛选的,就优先考虑使用分组前筛选

    2、group by 子句支持单个字段分组,多个字段分组(多个字段之间用逗号隔开没有顺序要求),表表达式或函数(用得较少)

    3、也可以添加排序(排序放在整个分组查询的最后)

    */

    #案例1:查询每个工种的最高工资

    select max(salary), job_id 

    from employees

    group by job_id

    #案例2、查询每个位置上的部门个数

    select count(*), location_id

    from departments

    group by location_id

    #添加筛选条件

    #案例1:查询邮箱中包含a字符的,每个部门的平均工资

    select avg(salary), department_id

    from employees

    where email like '%a%'

    group by department_id

    #案例2、查询有奖金的每个领导手下员工的最高工资

    select max(salary), manager_id

    from employees

    where commission_pct is not null

    group by manager_id

    #添加复杂的筛选条件

    #实例1:查询哪个部门的员工个数>2

    1.查询每个部门的员工个数

    select count(*), department_id

    from employees

    group by department_id

    2.根据1的结果进行筛选,查询哪个部门对赌员工个数>2

    select count(*), department_id

    from employees

    group by department_id

    having count(*)>2

    #案例2:查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资

    #1.查询每个工种有奖金的员工的最高工资

    select max(salary), job_id

    from employees

    where commission_pct is not null

    group by job_id

    2.根据1的结果继续筛选,最高工资>12000

    select max(salary), job_id

    from employees

    where commission_pct is not null

    group by job_id

    having max(salary) > 12000

    #案例3:查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资

    1. 查询每个领导手下的最低工资

    select min(salary), manager_id

    from employees

    group bu manager_id

    2.添加筛选条件:编号>102

    select min(salary), manager_id

    from employees

    where manager_id > 102

    group bu manager_id

    3.添加筛选条件最低工资>5000

    select min(salary), manager_id

    from employees

    where manager_id > 102

    group bu manager_id

    having min(salary) > 5000

    #按表达式或函数分组

    #案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些

    1.查询每个长度的员工个数

    select count(*) , length(last_name) len_name

    from employees

    group by length(last_name)r

    2.添加筛选条件

    select count(*)  , length(last_name) len_name

    from employees

    group by length(last_name)

    having count(*) > 5

    别名,【不通用】

    select count(*)  c, length(last_name) len_name

    from employees

    group bylen_name

    having c

    #按多个字段分组

    #案例:查询每个部门每个工种的员工的平均工资

    select avg(salary), department_id, job_id

    from employees

    group_by department_id, job_id

    #添加排序

    #案例:查询每个部门每个工种的员工的平均工资,并且按平均工资的高低显示

    select avg(salary), department_id, job_id

    from employees

    where department_id is not null

    group_by department_id, job_id

    having avg(salary) > 10000

    order by avg(salary) desc

    别名

    select avg(salary) a, department_id, job_id

    from employees

    where department_id is not null

    group_by department_id, job_id

    having a > 10000

    order by a desc

    案例:查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内

    select min(salary), manager_id

    from employees

    where manager_id is not null

    group by manager_id

    having min(ssalary) >= 6000

    #进阶6:连接查询

    含义:又称多表查询、当查询的字段来自于多个表时,就会用到连接查询

    笛卡尔乘积现象:表1 有m行,表2有n行,结果=m*n行

    发生原因:没有有效的连接条件

    如何避免:添加有效的连接条件

    分类:

            按年代分类:

            sql192标准:仅仅支持内连接

            sql199标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接

            按功能分类:

                内连接:

                    等值连接

                    非等值连接

                    自连接

                外连接

                    左外连接

                    右外连接

                    全外连接

                交叉连接

    #一、sql192标准

    #1、等值连接

        -多表等值连接的结果为多表的角几部分

        -n表连接,至少需要n-1个连接条件

        -多表的顺序没有要求

        -一般需要为表起别名

        -可以搭配签名介绍的所有字句使用,比如排序、分组、筛选

    #案例1:查询女神名和对应的男神名

    select name, boyName form boys, beauty

    where beauty.boyfriend_id = boys.id

    #案例2:查询员工名和对应的部门名

    select last_name, department_name

     from employees,departments

    where employees.department_id = departments.department_id

    #2、查询员工名、工种号、工种名;为表起别名,提高语句的简洁度,区分多个重名的字段

    注意:如果为表起了别名,则查询的字段就不能使用原来的表名去限定

    select last_name, e.job_id, job_title

    from employees AS e, jobs j

    where e.job_id = j.job_id

    #3、两个表的顺序是否可以调换

    select last_name, e.job_id, job_title

    from  jobs j, employees AS e

    where e.job_id = j.job_id

    #4、可以加筛选?

    #案例:查询有奖金的员工名、部门名

    select last_name, department_name, commission_pct I

    from employees e, departments d

    where e.department_id = d.department_id AND e.commission_pct IS NOT NULL

    #案例2:查询城市名中第二个字符为o的部门名和城市名

    select department_name, city

    from departments d, locations l

    where d.location_id = l.location_id 

    AND city LIKE '_o%'

    #5、可以加分组?

    #案例1:查询每个城市的部门个数

    select count(*) 个数 , city 

    from departments d, locations l

    where d.location_id = l.location_id

    GROUP BY city 

    #案例2:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资

    select department_name, d.manager_id, min(salary)

    from departments d, employees e

    where d.department = e.department_id

    AND commisson_pch IS NOT NULL

    GROUP BY department_name, d.manager_id

    #6、可以加排序

    #案例:查询每个工种的工种名和员工的个数,并且按员工个数降序

    select job_title, count(*)

    from employees e, jobs j

    where e.job_id = j.job_id 

    GROUP BY job_title

    ORDER BY count(*) DESC

    #7、可以实现三表连接?

    #案例:查询员工名、部门名和所在的城市

    select last_name, department_name, city

    from employees e, departments d, locations l

    where e.department_id = d.department_id

    AND d.location_id = l.location_id

    AND city LIKE 'S%'

    ORDER BY department_name DESC

    #2、非等值连接

    #案例1:查询员工的工资和工资级别

    select salary, grade_level

    from employess e, job_grades j

    where salary BETWEEN g.lowest_sal AND g.highest_sal

    AND g.grade_level = 'A'

    #3、自连接

    #案例:查询员工名和上级的名称

    select e.employee_id, e.last_name, m.employee_id, m.last_name

    from employees e, employees m

    where e.manager_id = m.employee_id

    #二、sql99语法

    /*

        语法:select 查询列表

                    form 表1 别名 【连接类型】

                    join 表2 别名 on 连接条件

                    where 筛选条件

                    【group by 分组】

                    【having 筛选条件】

                    【order by 排序列表】

        内连接:inner

        外连接

            左外:left【outer】

            右外:right  【outer】

            全外:full  【outer】

        交叉连接:cross

    */

    一:内连接

    语法:

    select 查询列表

    from 表1 别名

    inner join 表2 别名

    on 连接条件

    分类:

    等值

    非等值

    自连接

    特点:

        -添加排序、分组、筛选

        -inner 可以省略

        -筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读

        -inner join 连接和sql92语法中的等值连接效果是一样的,都是查询多表的交集

    #1、等值连接

    案例1:查询员工名、部门名

    select last_name, department_name

    from employees e

    inner join departments d 

    ON e.department_id = d.department_id

    案例2:查询名字中包含e的员工名和工种名(筛选)

    select last_name, job_title

    from employees e

    inner join jobs j

    ON e.job_id = j.job_id

    where e.last_name LIKE '%e%'

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

    -查询每个城市的部门个数

    -在1结果上筛选

    select city, count(*) 部门个数

    from departments d

    inner join locations l

    ON d.location_id = l.location_id

    GROUP BY city 

    having count(*) > 3

    案例4:查询哪个部门的部门员工个数>3的部门名和员工个数,并按照个数降序(排序)

    -查询每个部门的员工个数

    select count(*), department_name

    from employees e

    innet join departments d

    ON e.department_id = d.department_id

    GROUP BY department_name

    -在1结果上筛选员工个数>3的记录,并排序

    select count(*), department_name

    from employees e

    innet join departments d

    ON e.department_id = d.department_id

    GROUP BY department_name

    having count(*) > 3

    ORDER BY count(*) DESC 

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

    select last_name, department_name, job_title

    from employees e

    inner join departments d ON e.department_id = d.department_id

    innert join j ON e,job_id = j.job_id

    ORDER BY department_name DESC

    二:非等值连接

    #查询员工的工资级别

    select salary, grade_level

    from employees e

    inner join job_grades g

    ON e.salary BETWEEN g.lowest_sal AND g.highest_sal

    #查询工资级别的个数>2的个数,并且按工资级别降序

    select count(*), grade_level

    from employees e

    inner join job_grades g

    ON e.salary BETWEEN g.lowest_sal AND g.highest_sal

    GROUP BY grade_level

    having count(*) > 20

    ORDER BY grade_level DESC

    三:自连接

    #查询员工的名字,上级的名字

    select e.last_name, m.last_name

    from employees e

    inner join employees m

    on e.manager_id = m.employee_id

    where e.last_name LIKE '%k%'

    二、外连接

    /*

    应用场景:用于查询一个表中有,另一个表没有的记录

    特点:

    1、外连接的查询结果为主表中的所有记录

        如果从表中有和他匹配的,则显示匹配的值

        如果从表中没有和他匹配的,则显示null

        外连接查询结果=内连接结果+主表中有而从表没有的记录

    2.左外连接, left join 左边的是主表

        右外链接,right join 右边的是主表

    3.左外和右外交换两个表的顺序,可以实现同样的结果

    4.全外连接=内连接的结果+表1中有但表2没有的+表2中有单表1没有的

    */

    #案例1:查询哪个部门没有员工

    #左外

    select d.*, e.employee_id

    from departments d

    left outer join employees e

    ON d.department_id = e.department_id

    where e.employee_id IS NULL

    #右外

    select d.*, e.employee_id

    from employees e

    left outer join department d

    ON d.department_id = e.department_id

    where e.employee_id IS NULL

    #全外

    select b.*, bo.*

    from beauty b

    full outer join boys bo

    ON b.boyfiiend_id IS NULL

    #交叉连接

    select b.*, bo.*

    from beauty b

    CROSS JOIN boys bo

    #sql92 和 sql99

    功能:sql99支持的较多

    可读性:sql99

    #案例一、查询编号>3的女神的男朋友信息,如果有则列出详细,如果没有,用null填充

    select b.id, b.name, bo.*

    from beauty b

    left outer join boys bo

    ON b.boyfriend_id  = bo.id

    where b.id > 3

    #案例二、查询哪个城市没有部门

    select city, d.*

    from departments d

    right outer join locations l

    ON d.location_id = l.location_id

    where d.department_id is null

    #三、查询部门名为SAL或IT的员工信息

    select e.*, d.department_name

    from departments d

    left join employees e

    ON d.department_id = e.department_id

    where d.department_name IN ('SAL', 'IT')

    相关文章

      网友评论

          本文标题:sql笔记 P49-86

          本文链接:https://www.haomeiwen.com/subject/ejppwltx.html