最近做的sql练习题,保存下来。
1.查找最晚入职员工的所有信息
CREATE TABLE `employees` (
`emp_no` int(11) 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 order by hire_date desc limit 1
2.查找入职员工时间排名倒数第三的员工所有信息
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 order by hire_date desc limit 2,1
3.查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号dept_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 `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`));
思路:这应该是一道比较简单的表连问题,salaries这张表加上dept_manager这个表里面的`dept_no`字段加上两个where限制条件
select a.emp_no,a.salary,a.from_date,a.to_date,b.dept_no
from salaries a
inner join dept_manager b
on a.emp_no=b.emp_no
where a.to_date='9999-01-01'
and b.to_date='9999-01-01'
4.查找所有已经分配部门的员工的last_name和first_name
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 b.last_name,b.first_name,a.dept_no
from dept_emp a
left join employees b
on a.emp_no=b.emp_no
5.
题目描述
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`));
思路:更换连接的主表即可,既然包括没有分配部门的应当用employees为主表,但是这里我用right join没有调试成功
select b.last_name,b.first_name,a.dept_no
from employees b
left join dept_emp a
on a.emp_no=b.emp_no
6.查找所有员工入职时候的薪水情况,给出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`));
思路:这道题left join 和 innner join都可以通过,查找满足from_date=hire_date并按要求排序即可
select a.emp_no,b.salary
from employees a
left join salaries b
on a.emp_no=b.emp_no
where a.hire_date=b.from_date
order by a.emp_no desc
7.查找薪水涨幅超过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`));
思路:首先按照emp_no这个字段进行分组,然后添加限定条件having ,group后面的限定条件不能用where 而应该用having
select emp_no,count(distinct(salary)) t
from salaries
group by emp_no
having t>15
8.找出所有员工当前(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`));
思路:这道题也是属于简单题,选择salary按照where条件筛选,并且按照order by 排序,下面是我的代码
select distinct(salary)
from salaries
where to_date='9999-01-01'
order by salary desc
看了一下别人的思路,有个问题,
对于distinct,groupby的性能。
- 数据量非常巨大时候,比如1000万中有300W重复数据,这时候的distinct的效率略好于group by;
- 对于相对重复量较小的数据量比如1000万中1万的重复量,用groupby的性能会远优于distnct。
select salary from salaries where to_date='9999-01-01' group by salary order by salary DESC
9.获取所有部门当前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`));
思路:第一次调试的时候 a和 b与下面结果相反,导致没有运行成功,这个和第三题有些类似,逻辑是差不多的,选择不同的字段。
select dept_no,a.emp_no,salary
from salaries b
inner join dept_manager a
on a.emp_no=b.emp_no
where a.to_date='9999-01-01' and b.to_date='9999-01-01'
10.获取所有非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`));
思路:首先把dept_manager里面的员工号找出来,用where语句筛选
select emp_no from employees
where emp_no not in (select emp_no from dept_manager)
11.获取所有员工当前的manager,如果当前的manager是自己的话结果不显示,当前表示to_date='9999-01-01'。
结果第一列给出当前员工的emp_no,第二列给出其manager对应的manager_no。
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 `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`));
思路:a和b根据部门编号表连,选择相应的字段,最后用where控制当前时间并且把员工号是部门经理的剔除掉。
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 not in (select emp_no from dept_manager )
大神的优化如下:没有用到表连,查询时间可以减少12ms
SELECT de.emp_no,dm.emp_no AS manager_no
FROM dept_manager AS dm,dept_emp AS de
WHERE de.emp_no <> dm.emp_no
AND de.dept_no = dm.dept_no
AND dm.to_date='9999-01-01';
12.获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
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 `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 a.dept_no,a.emp_no,max(b.salary) as salary
from dept_emp a
inner 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
13.从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
CREATE TABLE IF NOT EXISTS "titles" (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date DEFAULT NULL);
思路:count可以按照title计数也可以emp_no进行计数,首先选择分组,最后由having限定筛选条件
select title,COUNT(emp_no) as t
from titles
group by title
having t>=2
14.从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
注意对于重复的emp_no进行忽略。
CREATE TABLE IF NOT EXISTS "titles" (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date DEFAULT NULL);
思路:这道题应该就是上面13题目的变形了,这里考察加入一个distinct。
select title,COUNT(distinct(emp_no)) as t
from titles
group by title
having t>=2
15.查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
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`));
思路:选择全部信息,用where限定emp_no为奇数,并且last_name不为Mary,这里要记得mary加上引号,因为I是一个字段的值。
select *
from employees
where emp_no%2<>0 and last_name<>'Mary'
order by hire_date desc
16.统计出当前各个title类型对应的员工当前薪水对应的平均工资。结果给出title以及平均工资avg。
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`));
CREATE TABLE IF NOT EXISTS "titles" (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date DEFAULT NULL);
思路:我这个思路比较固定了,先把两个表连接起来,然后找到当前,这个上面已经多次涉及了,然后按照title分组进行avg运算
select a.title,avg(b.salary) avg
from titles a
inner 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.title
17.获取当前(to_date='9999-01-01')薪水第二多的员工的emp_no以及其对应的薪水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`));
思路:这个和按入职时间排序的题差不多,注意limit从0开始排列的
select emp_no,salary
from salaries
where to_date='9999-01-01'
order by salary desc limit 1,1
18.查找当前薪水(to_date='9999-01-01')排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
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`));
思路:这道题不准使用order by很有意思了就,想法就是先把最高的薪水去掉,然后再选最高的,这样就省去了order by。在选择最高的时候也要注意需要当前薪水。
select b.emp_no,max(b.salary)as salary,a.last_name,a.first_name
from employees a
inner join salaries b
on a.emp_no=b.emp_no
where b.to_date='9999-01-01'
and b.salary not in (select max(salary) from salaries )
19.查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
CREATE TABLE `departments` (
`dept_no` char(4) NOT NULL,
`dept_name` varchar(40) NOT NULL,
PRIMARY KEY (`dept_no`));
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`));
思路:首先通过
dept_emp.dept_no
把前两个表连接起来,这个是为了找到dept_name,然后左连为了找到包括暂时没有分配部门的员工
select a.last_name,a.first_name,b.dept_name
from employees a
left join (select * from departments join dept_emp on departments.dept_no=dept_emp.dept_no ) as b
on a.emp_no=b.emp_no
20.查找员工编号emp_now为10001其自入职以来的薪水salary涨幅值growth
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
SELECT ((SELECT salary FROM salaries WHERE emp_no = 10001 ORDER BY to_date DESC LIMIT 1)
- (SELECT salary FROM salaries WHERE emp_no = 10001 ORDER BY to_date asc LIMIT 1)
) as growth
21.查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_noy以及其对应的薪水涨幅growth,并按照growth进行升序
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`));
思路:这道题我做了很久没有做出来,最后看的别人的思路。1.首先找到当前薪资和入职时候的薪资,用左连接把员工号和薪资先提取出来,然后再inner join 找到growth这个字段。
select sstart.emp_no,(snow.salary-sstart.salary) AS growth
from (select s.emp_no,s.salary from employees e left join salaries s on s.emp_no=e.emp_no where e.hire_date=s.from_date) as sstart
inner join (select s.emp_no,s.salary from employees e left join salaries s on s.emp_no=e.emp_no where s.to_date='9999-01-01') as snow
on sstart.emp_no=snow.emp_no
ORDER BY growth
22.统计各个部门对应员工涨幅的次数总和,给出部门编码dept_no、部门名称dept_name以及次数sum
CREATE TABLE `departments` (
`dept_no` char(4) NOT NULL,
`dept_name` varchar(40) NOT NULL,
PRIMARY KEY (`dept_no`));
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 `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`));
思路如下:首先找到员工号和涨薪次数的技术表a,然后根据员工号和员工部门表连接起来,然后根据部门号和名称连接起来。
select c.dept_no,d.dept_name,c.sum
from
(select b.dept_no,sum(a.num) as sum
from dept_emp b
inner join (select emp_no,count(salary)as num from salaries group by emp_no) as a
on a.emp_no=b.emp_no
group by b.dept_no) as c
inner join departments d
on c.dept_no=d.dept_no
23.对所有员工的当前(to_date='9999-01-01')薪水按照salary进行按照1-N的排名,相同salary并列且按照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 s1.emp_no,s1.salary,count(distinct s2.salary) rank
from salaries s1, salaries s2
where s1.salary <= s2.salary and s1.to_date = '9999-01-01' and s2.to_date = '9999-01-01'
group by s1.emp_no order by rank;
24.获取所有非manager员工当前的薪水情况,给出dept_no、emp_no以及salary ,当前表示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 `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`));
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 d.dept_no,e.emp_no,s.salary
from dept_emp d,employees e,salaries s
where d.emp_no = e.emp_no and e.emp_no = s.emp_no
and e.emp_no not in(select emp_no from dept_manager where to_date='9999-01-01')
and s.to_date='9999-01-01' and d.to_date='9999-01-01'
SELECT d.dept_no,e.emp_no,salary FROM employees e JOIN dept_emp d ON d.emp_no = e.emp_no JOIN salaries s ON e.emp_no = s.emp_no
WHERE d.to_date = '9999-01-01' AND s.to_date = '9999-01-01' AND e.emp_no
NOT IN( SELECT emp_no FROM dept_manager WHERE to_date = '9999-01-01')
还有一种就是连续用两个join的,感觉这中方法还是比较容易理解的。
25.获取员工其当前的薪水比其manager当前薪水还高的相关信息,当前表示to_date='9999-01-01',
结果第一列给出员工的emp_no,
第二列给出其manager的manager_no,
第三列给出该员工当前的薪水emp_salary,
第四列给该员工对应的manager当前的薪水manager_salary
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 `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 a.emp_no,b.emp_no as manager_no,a.salary as emp_salary,b.salary as manager_salary
from
(select de.emp_no,de.dept_no,sa.salary from dept_emp de
join salaries sa on de.emp_no=sa.emp_no where de.to_date='9999-01-01' and sa.to_date='9999-01-01') as a
join (select dept.dept_no,dept.emp_no,sal.salary from dept_manager dept join
salaries sal on dept.emp_no=sal.emp_no where dept.to_date='9999-01-01' and sal.to_date='9999-01-01')as b
on a.dept_no=b.dept_no
where a.salary>b.salary
思路:首先找到相应的员工薪水表,找到经理薪水表,然后根据部门编号做join,筛选salary更大的就可以
26.汇总各个部门当前员工的title类型的分配数目,结果给出部门编号dept_no、dept_name、其当前员工所有的title以及该类型title对应的数目count
CREATE TABLE `departments` (
`dept_no` char(4) NOT NULL,
`dept_name` varchar(40) NOT NULL,
PRIMARY KEY (`dept_no`));
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 IF NOT EXISTS "titles" (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,
`to_date` date DEFAULT NULL);
SELECT de.dept_no, dp.dept_name, t.title, COUNT(t.title) AS count
FROM titles AS t
INNER JOIN dept_emp AS de
ON t.emp_no = de.emp_no AND de.to_date = '9999-01-01' AND t.to_date = '9999-01-01'
INNER JOIN departments AS dp
ON de.dept_no = dp.dept_no
GROUP BY de.dept_no, t.title
思路:这道题应该是以title为主表的,然后连接dept_emp,然后连接departments
27.给出每个员工每年薪水涨幅超过5000的员工编号emp_no、薪水变更开始日期from_date以及薪水涨幅值salary_growth,并按照salary_growth逆序排列。
提示:在sqlite中获取datetime时间对应的年份函数为strftime('%Y', to_date)
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 s2.emp_no, s2.from_date, (s2.salary - s1.salary) AS salary_growth
FROM salaries AS s1, salaries AS s2
WHERE s1.emp_no = s2.emp_no
AND salary_growth > 5000
AND (strftime("%Y",s2.to_date) - strftime("%Y",s1.to_date) = 1
OR strftime("%Y",s2.from_date) - strftime("%Y",s1.from_date) = 1 )
ORDER BY salary_growth DESC
思路:关键点在于每年用和之差为1进行选取,最后用order by 限定顺序
28.
题目描述
字段 | 说明 |
film_id | 电影id |
title | 电影名称 |
description | 电影描述信息 |
CREATE TABLE IF NOT EXISTS film (film_id smallint(5) NOT NULL DEFAULT '0',title varchar(255) NOT NULL,description text,PRIMARY KEY (film_id));
字段 | 说明 |
category_id | 电影分类id |
name | 电影分类名称 |
last_update | 电影分类最后更新时间 |
CREATE TABLE category (category_id tinyint(3) NOT NULL ,name varchar(25) NOT NULL, `last_update` timestamp,PRIMARY KEY ( category_id ));
字段 | 说明 |
film_id | 电影id |
category_id | 电影分类id |
last_update | 电影id和分类id对应关系的最后更新时间 |
CREATE TABLE film_category (film_id smallint(5) NOT NULL,category_id tinyint(3) NOT NULL, `last_update` timestamp);
FROM film AS f, film_category AS fc, category AS c,
(SELECT category_id FROM film_category GROUP BY category_id HAVING COUNT(category_id) >= 5) AS cc
WHERE f.description LIKE '%robot%'
AND f.film_id = fc.film_id
AND fc.category_id = c.category_id
AND c.category_id = cc.category_id
29.
字段 | 说明 |
film_id | 电影id |
title | 电影名称 |
description | 电影描述信息 |
CREATE TABLE IF NOT EXISTS film (film_id smallint(5) NOT NULL DEFAULT '0',title varchar(255) NOT NULL,description text,PRIMARY KEY (film_id));
字段 | 说明 |
category_id | 电影分类id |
name | 电影分类名称 |
last_update | 电影分类最后更新时间 |
CREATE TABLE category (category_id tinyint(3) NOT NULL ,name varchar(25) NOT NULL, `last_update` timestamp,PRIMARY KEY ( category_id ));
字段 | 说明 |
film_id | 电影id |
category_id | 电影分类id |
last_update | 电影id和分类id对应关系的最后更新时间 |
CREATE TABLE film_category (film_id smallint(5) NOT NULL,category_id tinyint(3) NOT NULL, `last_update` timestamp);
select f.film_id,f.title
from film f
left join film_category fc
on f.film_id=fc.film_id
where fc.category_id is null