Article directory
1. Basic query review
- Query employees whose salary is higher than 500 or whose position is MANAGER, and their initials must be capital J;
select * from emp where (sal>500 or job='MANGER') and ename like 'J%';
- Sort by department number in ascending order and employee salary in descending order;
select * from emp order by deptno, sal desc;
- Sort in descending order using annual salary;
select ename, sal*12+ifnull(comm, 0) as '年薪' from emp order by 年薪 desc;
- Display the name and job title of the highest paid employee;
select ename, job from emp where sal = (select max(sal) from emp);
- Display information about employees whose salaries are higher than the average salary;
select ename, sal from emp where sal > (select avg(sal) from emp);
- Shows the average and maximum salary for each department;
select deptno, format(avg(sal), 2), max(sal) from emp group by deptno;
- Display the department number with an average salary below 2000 and its average salary;
select deptno, avg(sal) as avg_sal from emp group by deptno having avg_sal<2000;
- Shows the total number of employees in each position and the average salary
select job, count(*), format(avg(sal), 2) from emp group by job;
2.Multiple table query
In actual development, data often comes from different tables, so multi-table queries are required. In this section, we use a simple company management system with three tables EMP, DEPT, and SALGRADE to demonstrate how to perform multi-table queries.
Case
- Display the employee name, employee salary and the name of the department. Because the above data comes from the EMP and DEPT tables, it needs to be queried jointly;
select emp.ename, emp.sal, dept.dname from emp, dept;
- But in fact, we only need the deptno field record in the emp table = the deptno field record in the dept table;
select emp.ename, emp.sal, dept.dname from emp, dept where emp.deptno = dept.deptno;
- Display the department name, employee name and salary of department number 10;
select emp.ename, emp.sal, dept.dname from emp, dept where emp.deptno = dept.deptno and dept.deptno = 10;
- Display the name, salary, and salary level of each employee;
select ename, sal, grade from emp, salgrade where emp.sal between losal and hisal;
3.Self link
自连接是指在同一张表连接查询
;
Case
- Display the number and name of employee FORD’s superior leader (mgr is the employee leader’s number – empno);
Use subquery
select empno, ename from emp where emp.empno = (select mgr from emp where ename = 'FORD');
Use multi-table query (self-query)
- Use the alias of the table, from emp leader, emp worker, to give your own table an alias. Because you need to do it first
笛卡尔积
, the alias can be recognized first;
select leader.empno, leader.ename from emp leader, emp worker
-> where leader.empno = worker.mgr and worker.ename = 'FORD';
4. Subquery
子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询
;
4.1 Single row subquery
单行子查询即返回一行记录的子查询
;
Case
- Display employees in the same department of SMITH;
select * from emp where deptno = (select deptno from emp where ename='smith');
4.2 Multi-row subquery
即返回多行记录的子查询
;
Case
in关键字
;Query the name, position, salary, and department number of employees who have the same job position as department No. 10, but do not include 10 themselves;
select ename, job, sal, deptno from emp where job in
-> (select distinct job from emp where deptno = 10) and deptno <> 10;
all关键字
;Display the name, salary and department number of employees whose salary is higher than that of all employees in department 30;
select ename, sal, deptno from emp where sal > all(
-> select sal from emp where deptno = 30);
any关键字
;Display the name, salary and department number of employees whose salary is higher than that of any employee in department 30 (including employees in their own department);
select ename, sal, deptno from emp where sal > any(
-> select sal from emp where deptno = 30);
4.3 Multi-column subquery
单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询则是指查询返回多个列数据的子查询语句
;
Case
- Query all employees with the same department and position as SMITH, excluding SMITH himself;
select ename from emp where (deptno, job) = (
-> select deptno, job from emp where ename = 'SMITH') and ename <> 'SMITH';
4.4 Using subqueries in the from clause
子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用
;
Case
- Display the name, department, salary, and average salary of each employee whose salary is higher than the average salary of his or her department;
select ename, deptno, sal, format(asal, 2) from emp,
-> (select avg(sal) asal, deptno dt from emp group by deptno) tmp
-> where emp.sal > tmp.asal and emp.deptno = tmp.dt;
- Find the name, salary, department, and maximum salary of the person with the highest salary in each department;
select emp.ename, emp.sal, emp.deptno, ms from emp,
-> (select max(sal) ms, deptno from emp group by deptno) tmp
-> where emp.deptno = tmp.deptno and emp.sal = tmp.ms;
-
Display the information of each department (department name, number, address) and number of personnel;
-
Method 1: Use multiple tables;
select dept.dname, dept.deptno, dept.loc, count(*) '部门人数' from emp,
-> dept where emp.deptno = dept.deptno group by dept.deptno, dept.dname, dept.loc;
- Method 2: Use subquery;
select dept.deptno, dname, mycnt, loc from dept,
-> (select count(*) mycnt, deptno from emp group by deptno) tmp
-> where dept.deptno = tmp.deptno;
5. Combined queries
在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all
;
5.1 union
该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行
;
Case
- Find people whose salary is greater than 2,500 or whose position is MANAGER;
select ename, sal, job from emp where sal > 2500 union
-> select ename, sal, job from emp where job = 'MANGER';
5.2 union all
该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行
;
Case
- Find people whose salary is greater than 25,000 or whose position is MANAGER
select ename, sal, job from emp where sal > 2500 union
-> select ename, sal, job from emp where job = 'MANGER';
6. Inner and outer joins of tables
- Table connections are divided into internal connections and external connections;
6.1 Inner joins
内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我们前面学习的查询都是内连接,也是在开发过程中使用的最多的连接查询
;
grammar
select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件;
Case
- Display SMITH’s name and department name;
-- 用前面的写法
select ename, dname from emp, dept where
-> emp.deptno = dept.deptno and ename = 'SMITH';
-- 用标准的内连接写法
select ename, dname from emp inner join dept on
-> emp.deptno = dept.deptno and ename = 'SMITH';
6.2 Outer joins
- Outer joins are divided into left outer joins and right outer joins;
6.2.1 Left outer join
如果联合查询,左侧的表完全显示我们就说是左外连接
;
grammar
select 字段名 from 表名1 left join 表名2 on 连接条件
Case
-- 建两张表
create table stu (id int, name varchar(30)); -- 学生表
insert into stu values(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
create table exam (id int, grade int); -- 成绩表
insert into exam values(1, 56),(2,76),(11, 8);
- Query the scores of all students. If the student has no scores, the student's personal information will also be displayed;
-- 当左边表和右边表没有匹配时,也会显示左边表的数据
select * from stu left join exam on stu.id = exam.id;
6.2.2 Right outer join
如果联合查询,右侧的表完全显示我们就说是右外连接
;
grammar
select 字段 from 表名1 right join 表名2 on 连接条件
Case
- Jointly query the Stu table and the Exam table to display all scores, even if there is no student corresponding to this score, it must be displayed;
select * from stu right join exam on stu.id=exam.id;