查找入职员工时间排名倒数第三的员工所有信息
select * from employees
order by hire_date desc limit 2,1
#desc表示降序,从高到低,即时间最晚的最高,在最前面
#检索从第2行开始向前检索1条数据
查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号dept_no
select salaries.emp_no,salaries.salary,salaries.from_date,salaries.to_date,dept_manager.dept_no
#各变量名之前指明来自何表
from salaries inner join dept_manager
#结果中salaries在前,dept-no在后,则salaries为主表,顺序不可错
on(dept_manager.emp_no=salaries.emp_no)
where dept_manager.to_date='9999-01-01' and salaries.to_date='9999-01-01'
#条件查询,同时对两个表都要声明
查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括展示没有分配具体部门的员工
select last_name,first_name,dept_no
from employees left join dept_emp
#INNER JOIN 两边表同时有对应的数据,即任何一边缺失数据就不显示。
#LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据。
#RIGHT JOIN 会读取右边数据表的全部数据,即便左边表无对应数据。
on(employees.emp_no=dept_emp.emp_no)
查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序
select a.emp_no,b.salary
from employees a
inner join salaries b
#emp_no在前,主表为employees
#表别名可不加AS
on a.emp_no=b.emp_no and a.hire_date=b.from_date
order by a.emp_no desc
查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t
select emp_no,count(emp_no) as t
from salaries
group by emp_no
HAVING t > 15
获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date='9999-01-01'。
结果第一列给出当前员工的emp_no,第二列给出其manager对应的manager_no。
select a.emp_no,b.emp_no as manager_no
from dept_emp a inner join dept_manager b
on a.dept_no=b.dept_no
where a.to_date='9999-01-01' and b.to_date='9999-01-01' and a.emp_no<>b.emp_no
获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
select a.dept_no,b.emp_no,max(b.salary) as salary
from dept_emp a join salaries b
on a.emp_no=b.emp_no
where a.to_date = '9999-01-01' and b.to_date = '9999-01-01'
group by a.dept_no
或者
select a.dept_no,b.emp_no,b.salary
from dept_emp a join salaries b
on a.emp_no=b.emp_no
where a.to_date = '9999-01-01' and b.to_date = '9999-01-01'
group by a.dept_no
having b.salary =max(b.salary)
从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t
select title,count(title) as t
from titles
group by title
having t>=2
查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
select emp_no,birth_date,first_name,last_name,gender,hire_date
from employees
where emp_no%2<>0 and last_name<>"Mary"
order by hire_date desc
统计出当前各个title类型对应的员工当前薪水对应的平均工资。结果给出title以及平均工资avg
select b.title,avg(a.salary) as avg
from titles b left join salaries a
on b.emp_no=a.emp_no
where b.to_date = '9999-01-01' AND a.to_date = '9999-01-01'
group by b.title
获取当前(to_date='9999-01-01')薪水第二多的员工的emp_no以及其对应的薪水salary
select emp_no,salary
from salaries
where to_date='9999-01-01'
order by salary desc limit 1,1
查找当前薪水(to_date='9999-01-01')排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
select a.emp_no,max(b.salary),a.last_name,a.first_name
from employees a inner join salaries b
on a.emp_no=b.emp_no
where to_date='9999-01-01' and salary not in (select max(salary) from salaries)
查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
运用两次LEFT JOIN连接嵌套
1、第一次LEFT JOIN连接employees表与dept_emp表,得到所有员工的last_name和first_name以及对应的dept_no,也包括暂时没有分配部门的员工
2、第二次LEFT JOIN连接上表与departments表,即连接dept_no与dept_name,得到所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
select c.last_name,c.first_name,a.dept_name
from employees c left join dept_emp b on c.emp_no=b.emp_no
left join departments a on b.dept_no = a.dept_no
查找员工编号emp_no为10001其自入职以来的薪水salary涨幅值growth(最大值减最小值)
select max(salary)-min(salary) as growth
from salaries
where emp_no=10001
查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序
基本思路:整合成一张表(id, 来的时候的工资,最后的工资)
这张表第二个字段和第三个字段都涉及到了salary
所以一定会级联两次表salaries
也就是employees join salaries join salaries之后用on把条件筛选一个就可以了
select a.emp_no, (b.salary - c.salary) as growth
from employees a inner join salaries as b
on a.emp_no = b.emp_no and b.to_date = '9999-01-01'
inner join salaries as c
on a.emp_no = c.emp_no and a.hire_date = c.from_date
order by growth
统计各个部门对应员工涨幅的次数总和,给出部门编码dept_no、部门名称dept_name以及次数sum
关键是要将 每个部门分组,并分别统计工资记录总数,思路如下:
1、用INNER JOIN连接dept_emp表和salaries表,并以dept_emp.no分组,统计每个部门所有员工工资的记录总数
2、再将上表用INNER JOIN连接departments表,限制条件为两表的dept_no相等,找到dept_no与dept_name的对应关系,最后依次输出dept_no、dept_name、sum
select a.dept_no,a.dept_name,count(c.emp_no) as sum
from departments a inner join dept_emp b
on a.dept_no=b.dept_no
inner join salaries c
on b.emp_no=c.emp_no
group by a.dept_no
对所有员工的当前(to_date='9999-01-01')薪水按照salary进行按照1-N的排名,相同salary并列且按照emp_no升序排列
主要思想是复用salaries表进行比较排名,具体思路如下:
1、从两张相同的salaries表(分别为s1与s2)进行对比分析,先将两表限定条件设为to_date = '9999-01-01',挑选出当前所有员工的薪水情况。
2、本题的精髓在于 s1.salary <= s2.salary,意思是在输出s1.salary的情况下,有多少个s2.salary大于等于s1.salary,比如当s1.salary=94409时,有3个s2.salary(分别为94692,94409,94409)大于等于它,但由于94409重复,利用COUNT(DISTINCT s2.salary)去重可得工资为94409的rank等于2。其余排名以此类推。
select s1.emp_no,s1.salary,count(distinct s2.salary)
from salaries s1,salaries s2
where s1.to_date='9999-01-01' and s2.to_date='9999-01-01' and s1.salary<=s2.salary
group by s1.emp_no
order by s1.salary desc,s2.emp_no asc
获取所有非manager员工当前的薪水情况,给出dept_no、emp_no以及salary ,当前表示to_date='9999-01-01'
select a.dept_no,a.emp_no,d.salary
from dept_emp a inner join salaries d on a.emp_no=d.emp_no
inner join dept_manager b on a.dept_no=b.dept_no
where a.to_date='9999-01-01' and d.to_date='9999-01-01' and a.emp_no != b.emp_no
或者
select a.dept_no,a.emp_no,(select salary from salaries where emp_no=a.emp_no and to_date='9999-01-01') as salary
from dept_emp a left join dept_manager b on a.emp_no=b.emp_no
where a.to_date='9999-01-01' and b.emp_no is null
或者
select a.dept_no,a.emp_no,d.salary
from dept_emp a inner join salaries d on a.emp_no = d.emp_no and d.to_date = '9999-01-01'
where a.emp_no not in (select emp_no from dept_manager where to_date = '9999-01-01')
获取员工其当前的薪水比其manager当前薪水还高的相关信息,当前表示to_date='9999-01-01',
结果第一列给出员工的emp_no,
第二列给出其manager的manager_no,
第三列给出该员工当前的薪水emp_salary,
第四列给该员工对应的manager当前的薪水manager_salary
1.将dept_emp 与salaries连接得到employee的工资表 a
2.将dept_manager与salaries连接得到manager的工资表 b
3.将员工工资表a与管理员工资表b按照 同部门且员工工资大于管理员工资的条件连接
select a.emp_no ,b.emp_no, a.salary, b.salary
from
(dept_emp join salaries on dept_emp.emp_no = salaries.emp_no and dept_emp.to_date ='9999-01-01' and salaries.to_date ='9999-01-01')as a
join
(dept_manager join salaries on dept_manager.emp_no = salaries.emp_no and dept_manager.to_date='9999-01-01' and salaries.to_date='9999-01-01')as b
on a.dept_no = b.dept_no and a.salary > b.salary
汇总各个部门当前员工的title类型的分配数目,结果给出部门编号dept_no、dept_name、其当前员工所有的title以及该类型title对应的数目count
难点在于group by进行分组的时候,先从大范围分,也就是部门编号,再在部门内分组以及当前日期的书写
select a.dept_no,a.dept_name,c.title,count(c.title) as count
from dept_emp b inner join departments a
on b.dept_no = a.dept_no
inner join titles c on b.emp_no = c.emp_no and b.to_date=c.to_date and c.to_date='9999-01-01'
group by a.dept_no,c.title
查找描述信息中包括robot的电影对应的分类名称以及电影数目,而且还需要该分类对应电影数量>=5部
先将描述信息包含 “robot” 的电影分类及数量统计出来,再针对每一个分类,在 film_category 总表中该分类下所有电影的数量需要 >=5,最后筛选出满足条件的统计结果输出。
注意,统计出来 “robot” 的电影数量是多少就是多少,与 >=5 没有关系
select a.name,count(b.film_id) as count
from (select category_id from film_category group by category_id having count(category_id) >= 5) as cc , category a, film b , film_category c
where b.description like "%robot%"
and cc.category_id=a.category_id
and c.film_id=b.film_id
and a.category_id=c.category_id
使用子查询的方式找出属于Action分类的所有电影对应的title,description
in和=均可
select a.title,a.description
from film_category c,film a
where c.film_id=a.film_id and c.category_id in (select category_id from category where name ="Action")
获取select * from employees对应的执行计划
用 "EXPLAIN" 关键字或 "EXPLAIN QUERY PLAN" 短语,用于描述表的细节,具体说明与用法可参考:
explain select * from employees
将employees表的所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分
select last_name||" "||first_name as Name
from employees
CREATE TABLE actor
(
actor_id smallint(5) NOT NULL PRIMARY KEY,
first_name varchar(45) NOT NULL,
last_name varchar(45) NOT NULL,
last_update timestamp NOT NULL DEFAULT (datetime('now','localtime')) -- ,
-- PRIMARY KEY(actor_id)
)
insert into actor(actor_id,first_name,last_name,last_update)
values(1, 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'),(2, 'NICK', 'WAHLBERG', '2006-02-15 12:34:33')
用 INSERT OR IGNORE 来插入记录,或忽略插入与表内UNIQUE字段都相同的记录
用 INSERT OR REPLACE 来插入记录,或更新替代与表内UNIQUE字段都相同的记录
INSERT OR IGNORE INTO actor VALUES (3, 'ED', 'CHASE', '2006-02-15 12:34:33')
create table actor_name(
first_name varchar(45) not null,
last_name varchar(45) not null
);
insert into actor_name select first_name,last_name from actor;
触发器
CREATE TRIGGER audit_log AFTER INSERT ON employees_test
BEGIN INSERT INTO audit VALUES (NEW.ID, NEW.NAME);
END
删除emp_no重复的记录,只保留最小的id对应的记录。
delete from titles_test
where id not in (select min(id) from titles_test)
直接使用REPLACE INTO的话,就需要重新插入一条完整的新纪录,sql会自动代替id相同的记录
REPLACE INTO titles_test VALUES (5, 10005, 'Senior Engineer', '1986-06-26', '9999-01-01')
将titles_test表名修改为titles_2017
ALTER TABLE titles_test RENAME TO titles_2017