目录
1. 查找最晚入职员工的所有信息(单表)
2. 查找入职员工时间排名倒数第三的员工所有信息(单表)
3. 查找当前薪水详情以及部门编号dept_no(多表)
4. 查找所有已经分配部门的员工的last_name和first_name(多表)
5. 查找所有员工的last_name和first_name以及对应部门编号dept_no(多表)、
6. 查找所有员工入职时候的薪水情况(多表)
7. 查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t(单表)
8. 找出所有员工当前薪水salary情况(单表)
9. 获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary(多表)
10. 获取所有非manager的员工emp_no(多表)
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
select * from employees
where hire_date =(select max(hire_date) from employees)
最晚入职时间等于max(hire_date),得到时间后取出所有记录。
注意:尽量不要使用limit语句,因为可能当天有多条记录。
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
distinct时间去重:
select * from employees
where hire_date = (select distinct hire_date from employees
order by hire_date desc limit 2,1)
group by时间去重:
select * from employees
where hire_date = (select hire_date from employees group by hire_date
order by hire_date desc limit 2,1)
LIMIT m,n : 从第m+1条开始,取n条数据;
LIMIT n : 从第1条开始,取n条数据,是limit(0,n)的缩写。
用desc倒序,取出distinct去重(group by也可以)时间排名倒数的第3天。
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
直接从两个表中取出(注意顺序):
select s.*,d.dept_no
from salaries s, dept_manager d
where s.to_date='9999-01-01'
and d.to_date='9999-01-01'
and s.emp_no=d.emp_no
join方法:
select s.* ,d.dept_no
from salaries s
join dept_manager d
on s.emp_no=d.emp_no
where s.to_date = '9999-01-01'
and d.to_date='9999-01-01'
CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
select e.last_name, e.first_name, d.dept_no
from dept_emp d
inner join employees e
on d.emp_no=e.emp_no
用inner join方法,查找两张表共有的员工。from后面表的顺序不固定。
CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
select e.last_name, e.first_name, d.dept_no
from employees e
left join dept_emp d
on e.emp_no=d.emp_no
用left join方法,查找emp表中的所有员工,即使dept表中无数据(表示未分配部门)也可以返回。
查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
内连接:
select s.emp_no, s.salary
from salaries s
inner join employees e
on s.emp_no=e.emp_no
and s.from_date = e.hire_date
order by s.emp_no desc
并列查询:
select e.emp_no, s.salary
from employees e, salaries s
where e.emp_no = s.emp_no
and e.hire_date = s.from_date
order by e.emp_no desc
内连接和并列查询的区别:
内连接是取左右两张表的交集形成一个新表,用FROM并列两张表后仍然还是两张表。如果还要对新表进行操作则要用内连接。从效率上看应该FROM并列查询比较快,因为不用形成新表。
查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
select emp_no, count(emp_no) as t
from salaries
group by emp_no having t >15
用count函数统计次数,而用group by函数进行分类,having是筛选的条件。
找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
distinct:
select distinct salary
from salaries
where to_date='9999-01-01'
order by salary desc
group by:
select salary from salaries
where to_date='9999-01-01'
group by salary
order by salary desc
distinct可以实现,大表一般用distinct效率不高,大数据量的时候都禁止用distinct,建议用group by解决重复问题。
获取所有部门当前manager的当前薪水情况,给出dept_no, emp_no以及salary,当前表示to_date='9999-01-01'
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
并列查询:
select m.dept_no, m.emp_no, s.salary
from dept_manager m, salaries s
where m.to_date='9999-01-01'
and s.to_date='9999-01-01'
and s.emp_no = m.emp_no
join连接:
select m.dept_no, m.emp_no, s.salary
from dept_manager m
join salaries s
on m.emp_no = s.emp_no
and m.to_date = s.to_date
where s.to_date='9999-01-01'
获取所有非manager的员工emp_no
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
使用not in:
select emp_no
from employees
where emp_no not in (select emp_no from dept_manager)
left join连接两张表,再从此表中选出dept_no值为NULL对应的emp_no记录
select e.emp_no from employees e left join dept_manager m
on e.emp_no = m.emp_no
where dept_no is null
not in在实际使用中会转化成多表连接,而且不使用索引,因此还是用left_join代替会好一点。