sql练习题记录第一部分

最近做的sql练习题,保存下来。

1.查找最晚入职员工的所有信息

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 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.

题目描述

查找所有员工的last_name和first_name以及对应部门编号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`));

思路:更换连接的主表即可,既然包括没有分配部门的应当用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的性能。

  1. 数据量非常巨大时候,比如1000万中有300W重复数据,这时候的distinct的效率略好于group by;
  2. 对于相对重复量较小的数据量比如1000万中1万的重复量,用groupby的性能会远优于distnct。
所以我也觉得根据实际情况用group by和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`));

思路:这道题也是没有调试成功,然后看了下面大神的解析:

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。其余排名以此类推。
3、千万不要忘了GROUP BY s1.emp_no,否则输出的记录只有一条(可能是第一条或者最后一条,根据不同的数据库而定),因为用了合计函数COUNT()
4、最后先以 s1.salary 逆序排列,再以 s1.emp_no 顺序排列输出结果

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表
字段 说明
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表
字段 说明
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_category表
字段 说明
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);

查找描述信息中包括robot的电影对应的分类名称以及电影数目,而且还需要该分类对应电影数量>=5部
SELECT c.name AS name, COUNT(f.film_id) AS amount
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表
字段 说明
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表
字段 说明
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_category表
字段 说明
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);

使用join查询方式找出没有分类的电影id以及名称

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 









猜你喜欢

转载自blog.csdn.net/weixin_39666856/article/details/80443659
今日推荐