#添加筛选条件
#案例1:查询邮箱中包含a字符的,每个部门的平均工资
SELECT department_id,AVG(salary) 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.查询每个部门的员工个数
2.根据1的结果进行筛选,查询哪个部门的员工个数>2/
SELECT COUNT(*),department_id FROM employees
GROUP BY department_id
HAVING COUNT(*)>2;
#案例2:查询每个工种有奖金的员工的最高工资>12000
#的工种编号和最高工资
SELECT job_id,MAX(salary)
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>12000;
#案例3:查询领导编号>102的每个领导手下的最低工资》5000的领导编号是哪个,以及其最低工资
SELECT MIN(salary),manager_id FROM
employees WHERE manager_id>102
GROUP BY manager_id
HAVING MIN(salary)>5000;
#1.分组查询中的筛选条件分为两类
#分组前筛选 数据源 原始表 where
#分组后筛选 分组后的结果集 having
#分组函数做条件肯定是放在having之后
#按表达式分组
#案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些
SELECT LENGTH(last_name),COUNT(*)
FROM employees
GROUP BY LENGTH(last_name)
HAVING COUNT(*)>5;
#按多个字段分组 多个字段放在group by后面
#案例:查询每个部门的每个工种的员工的平均工资
SELECT department_id,job_id,AVG(salary)
FROM employees
GROUP BY department_id,job_id;
#添加排序
#案例:查询每个部门每个工种的员工的平均工资,并且按平均工资的高低显示
SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY department_id,job_id
ORDER BY AVG(salary) DESC;
#2.group by子句支持单个字段分组,多个字段分组(多个字段之间用逗号隔开没有顺序要求),
#表达式或函数(用的较少)
#3.也可以添加排序(排序在最后)
#练习
#1.查询个job_id员工工资的最大值,最小值,平均值,总和,并按job_id升序
SELECT MAX(salary),MIN(salary),SUM(salary),AVG(salary)
,job_id FROM employees
GROUP BY job_id
ORDER BY job_id;
#2.查询员工最高工资和最低工资的差距
SELECT MAX(salary) AS 最高工资,MIN(salary) AS 最低工资,MAX(salary)-MIN(salary)
FROM employees;
#3.查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id IS NOT NULL
GROUP BY manager_id
HAVING MIN(salary)>=6000;
#4.查询所有部门的编号,员工数量和工资平均值,并按平均工资降序
SELECT COUNT(*),AVG(salary),department_id
FROM employees
GROUP BY department_id
ORDER BY AVG(salary) DESC;
#5.选择具有各个job_id的人数
SELECT COUNT(*),job_id
FROM employees
GROUP BY job_id
ORDER BY job_id ASC;
#连接查询
/含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1有m行,表2有n行,结果=mn行
发生原因:没有有效的连接条件
如何避免:添加有效的连接条件
分类:
按年代分类:
sql92标准:仅仅支持内连接
sql99标准(推荐):支持内连接+外连接(左外和右外)+交叉连接
按功能分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全外连接
交叉连接
*
/
#sq92标准
/*
1.多表等值连接的结果为多表的交集部门
2.n表连接,至少需要n-1个连接条件
3.多表的顺序没有要求
4.一般需要为表起别名
5.可以搭配前面介绍的所有子句使用*/
#1.等值连接
#两个表的交集部分
#案例1:查询员工名和对应的部门名
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 e,jobs j
WHERE e.`job_id`=j.`job_id`;
#两个表的顺序是否可以调换
#案例2:查询员工名、工种号、工种名
SELECT last_name,e.`job_id`,job_title
FROM jobs j,employees e
WHERE e.`job_id`=j.`job_id`;
#4.加筛选
#案例:查询有奖金的员工名、部门名
SELECT last_name,department_name
FROM employees e,departments d
WHERE e.`commission_pct` IS NOT NULL AND e.`department_id`=d.`department_id`;
#查询城市名中第二个字符为o的城市名和部门名
SELECT city,department_name
FROM departments d,locations l
WHERE d.`location_id`=l.`location_id` AND city LIKE "_o%";
#5.分组
#查询每个城市的部门个数
SELECT COUNT(*),city,department_name
FROM departments d,locations l
WHERE d.`location_id`=l.`location_id`
GROUP BY city;
#查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
SELECT department_name,e.`manager_id`,MIN(salary)
FROM departments d,employees e
WHERE d.`department_id`=e.`department_id` AND e.`commission_pct` IS NOT NULL
GROUP BY department_name,e.`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.三表连接
#案例:查询员工名、部门名和所在的城市
S
ELECT 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`;
#非等值连接
#案例1:查询员工的工资和工资级别
CREATE TABLE job_grades
(grade_level VARCHAR(3),lowest_sal INT,highest_sal INT);
INSERT INTO job_grades VALUES('A',1000,2999);
INSERT INTO job_grades VALUES('B',3000,5999);
INSERT INTO job_grades VALUES('C',6000,9999);
INSERT INTO job_grades VALUES('D',10000,14999);
INSERT INTO job_grades VALUES('E',15000,24999);
INSERT INTO job_grades VALUES('F',25000,40000);
DELETE FROM job_grades WHERE grade_level='A' AND lowest_sal=25000;
SELECT *FROM job_grades;
SELECT salary, grade_level
FROM employees e,job_grades jb
WHERE salary BETWEEN jb.`lowest_sal` AND jb.`highest_sal`;
#原本这张表看成多张表
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`;
#一、显示员工的最大工资,平均工资
SELECT MAX(salary),AVG(salary)
FROM employees;
#二、查询员工表的employee_id,job_id,last_name,按department_id降序,salary升序
SELECT employee_id,job_id,last_name,salary
FROM employees
ORDER BY department_id DESC,
salary ASC;
#三、查询员工表的job_id中包含的a和e的并且a在e的前面
SELECT job_id
FROM employees
WHERE job_id LIKE '%a%e%';
#四、已知表student里面有id(学号),name,gradeId(年级编号)
#已知表grade,里面有id(年级编号),name(年级名)
#已知表result,里面有id,score,studentNo(学号)
CREATE TABLE student(id INT,s_name VARCHAR(10),gradeId INT);
CREATE TABLE grade(g_Id INT,g_name VARCHAR(10));
CREATE TABLE result(r_id INT,score INT, studentNo INT);
#五、显示当前日期,以及去前后空格,截取子字符串的函数
SELECT NOW();