1. Pseudo column: A virtual column, a column that does not exist in the original table, can be queried through the select statement.
I. Syntax: select pseudo column from table name
II. Detailed explanation:
rowid [understand]: uniquely identifies the physical location of a row of data. //Oracle query optimizer, used more in internal query, rarely used in application development
rownum [Key points]: Assign a logical number to each row of the queried data that meets the requirements. //Start from 1 and increment by 1.
III. Example:
//Query a row of data based on rowid (fast)
select * from employees where rowid = 'AAAR5kAAFAAAADNABD' file# block# row#
//Query all columns and rowids (table alias e, as is not allowed)
select e.*, rowid from employees e
//Query the top 5 employee information (number, name, salary) in the employee table
select employee_id , first_name , salary
from employees
where rownum <= 5;
//Query employee information after the 6th in the employee table (number, name, salary)
select employee_id , first_name , salary , rownum
from employees
where rownum > 5; //error has no matching results
Note: rownum is always generated from 1, it is only used in the environment of <=, and it is invalid in the environment of >=
//Query the information of the top 5 employees in the employee table by salary (number, name, salary)
select employee_id , first_name , salary
from employees
where rownum <= 5
order by salary desc //error
Reason: order by takes effect after where
Unfinished to be continued subquery
2. Subqueries: Nested Queries
I. Syntax: Same as basic query.
II. Detailed explanation:
将子查询“一行一列”的结果作为条件判断做第二次查询。
将子查询“多行一列”的结果作为枚举查询的判断条件做第二次查询。
将子查询“多行多列”的结果作为一张临时表进行第二次查询。
III. 用例:
//查询工资大于平均工资的员工信息(工号,名字,薪资)
思路:
1). 先查询员工平均薪资
select avg(salary) from employees; //平均薪资:6461.83177570093
2). 查询大于平均薪资的员工信息
select employee_id , first_name , salary
from employees
where salary > 6461.83177570093
SQL:
select employee_id , first_name , salary
from employees
where salary > (select avg(salary) from employees) //一行一列,才能和salary进行比较
//查询与姓氏为‘King’的员工在同一部门的员工信息(工号,名字,薪资,部门id)
思路:
1). 先查询 'King' 所在的部门编号
select department_id
from employees
where last_name = 'King' //部门编号:80、90
2). 再查询80、90号部门的员工信息
select employee_id , first_name , salary , department_id
from employees
where department_id in (80,90);
SQL:
select employee_id , first_name , salary , department_id
from employees
where department_id in (select department_id cfrom employees where last_name = 'King'); //N行一列
//查询员工表中工资排名前5员工的信息(编号,名字,薪资)
思路:
1). 先对所有员工的薪资进行排序(排序后的临时表)
select employee_id , first_name , salary
from employees
order by salary desc
2). 再查询临时表中前5行员工信息
select employee_id , first_name , salary
from (临时表)
where rownum <= 5;
SQL:合并
select employee_id , first_name , salary
from (select employee_id , first_name , salary from employees order by salary desc) //N行N列
where rownum <= 5;
三: 分页查询
//对工资降序后的员工表进行分页查询(每页显示10条数据,查看第1页数据(1~10),第2页11~20)
思路:
1).将原表中数据按照工资降序排序。
select * from employees order by salary desc;
2).为排序后的表增加一列(通过rownum增加一列RN)
select t.* , rownum "RN"
from (select * from employees order by salary desc) t
3).对临时表的查询结果过滤rn列值在11~20之间
select *
from (带有所有原表信息和行号的临时表)
where RN between 11 and 20;
SQL:合并
select *
from (select t.* , rownum "RN" from
(select * from employees order by salary desc) t)
where RN between 11 and 20;
四: 集合运算符:将多个查询结果合并为一张临时表。
I. 语法:A查询结果 集合运算符 B查询结果。
II. 详解:
union:并集。(联合去重)
union all:并集。(联合)
minus:差集。(减去)
intersect:交集。(较差)
III. 用例:
//查询60、70号部门员工信息
select * from employees where department_id in (60,70);
//查询70、90号部门员工信息
select * from employees where department_id in (90,70);
通过集合运算符将上面两条SQL语句的查询结果进行合并。
//union:并集将A和B的查询结果合并,重复数据只保留一份。
select * from employees where department_id in (60,70)
union
select * from employees where department_id in (90,70); //70号部门的员工信息只保留一份。
//union all:并集将A和B的查询结果合并,重复数据如数显示。
select * from employees where department_id in (60,70)
union all
select * from employees where department_id in (90,70); //70号部门的员工信息有几份保留几份
//minus:差集在A中删除与B中相同的结果。
select * from employees where department_id in (60,70)
minus
select * from employees where department_id in (90,70); //在A中删除与B中出现的重复数据,70号部门
AAAA//intersect:交集只保留A和B中重复的数据。
select * from employees where department_id in (60,70)
intersect
select * from employees where department_id in (90,70); //只保留重复的70号部门的数据
注:使用规则【重点】:查询结果可以来自与不同的表、不同的列。但列的个数必须相同、列的数据类型必须相同,最终结果中的列名和数据类型依赖与第一个结果集。
五:表连接查询
I. 语法:table1 连接 table2 on 连接条件
II. 详解:
外连接:
左外连接:主表left [outer] join 从表
右外连接:从表right [outer] join 主表
全外连接:主表 full [outer] join 主表
内连接:从表 inner join 从表
自连接:主表 连接方式 从表 (主从相同)
III. 用例:
//查询员工工号,名字,薪资,部门id,部门名称
问题:当查询数据来自于多张表时,使用表连接。
思路:将多张表基于关系列,拼接成一张大表,再取其中的某些列。
1). 左外连【重点】:table1 left join table2 on连接条件(table1为主表)
//查询所有员工信息,以及所对应的部门名称(没有部门的员工,也在查询结果中)
select e.employee_id , e.first_name , e.salary , d.department_name
from employees e left join departments d on e.department_id = d.department_id;
2). 右外连【了解】:table1 right join table2 on 连接条件(table2为主表)
//查询所有部门信息,以及此部门中的所有员工信息(没有员工的部门,也在查询结果中)
select e.employee_id , e.first_name , e.salary , d.department_name
from employees e right join departments d on e.department_id = d.department_id;
3). 全外连【了解】:table1 full join table2 on 连接条件(两张表都是主表)
//查询所有员工信息和所有部门信息(没有部门的员工、没有员工的部门,都在查询结果中)
select e.employee_id , e.first_name , e.salary , d.departmen0. t_name
from employees e FULL join departments d on e.department_id = d.department_id;
4). 内连接【了解】:table1 inner join table2 on 连接条件(两张表都是从表)
//查询所有有部门的员工信息(既不包括没有部门的员工,也不包括没有员工的部门)
select e.employee_id , e.first_name , e.salary , d.department_name
from employees e inner join departments d on e.department_id = d.department_id;
5). 自连接【重点】:table1 连接 table2 on 连接条件(逻辑上的两张表,物理上的同一张表)
//查询员工编号,名字,直接领导(经理)id,直接领导的名字
select e1.employee_id , e1.first_name , e1.manager_id , e2.first_name
from employees e1 left join employees e2 on e1.manager_id = e2.employee_id;
6). 三表连接查询:
--查询所有员工工号、名字、部门名称、部门所在国家ID
select * from employees e
inner join departments d
on e.department_id = d.department_id
inner join locations l
on d.location_id = l.location_id