本文共 7236 字,大约阅读时间需要 24 分钟。
SQL是每个学CS的必备技能,看上去内容就是些简单的建库建表、修表修值,增删查改,子查询,表连接,索引,存储过程,触发器,实则很难精通,遇到写复杂的SQL,反应半天也很难写出,看到别人写的答案,顿觉得豁然开朗。
下面记录写在牛客网上的刷题时遇到的不错的SQL题目以及对应的解题思路,以备自己复习之用。加油,秋招还未结束,抓住秋招最后的尾巴。。。
题目中主要用到的table表如下定义:
员工表employeesCREATE 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
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`));
部门员工表dept_emp
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`));
薪水表salaries
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`));
员工职称表titles
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);
部门表departments
CREATE TABLE `departments` (`dept_no` char(4) NOT NULL,`dept_name` varchar(40) NOT NULL,PRIMARY KEY (`dept_no`));
select * from employees where hire_date=(select max(hire_date) from employees);
select * from employees order by hire_date desc limit 2,1;
select last_name,first_name,d.dept_no from employees e ,dept_emp dwhere d.emp_no=e.emp_no and d.dept_no not NULL;
select e.emp_no from employees ewhere e.emp_no not in (select d.emp_no from dept_manager d);
select de.emp_no,dm.emp_no as manager_no from dept_emp de join dept_manager dmon de.dept_no=dm.dept_nowhere de.emp_no!=dm.emp_no and dm.to_date='9999-01-01' and de.to_date='9999-01-01';
select title,count(distinct(emp_no)) as t from titlesgroup by title having count(*)>=2;
select title,avg(salary) as avg from titles join salarieson titles.emp_no=salaries.emp_nowhere salaries.to_date='9999-01-01' and titles.to_date='9999-01-01'group by title;
select e.emp_no,max(salary) salary,last_name,first_name from employees ejoin salaries s on e.emp_no=s.emp_nowhere s.to_date='9999-01-01' and salary not in (select max(salary) from salaries);
select last_name,first_name,dept_name from employees e left join dept_emp de on e.emp_no=de.emp_noleft join departments d on de.dept_no=d.dept_no;
-- 严谨的思路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 limit 1)) as growth;-- 不严谨,必须最后一次工资大于最初工资/*select (max(salary)-min(salary)) as growth from salaries where emp_no=10001;*/
select tb1.emp_no,(salary_now - salary_start) as growth from (select emp_no,salary as salary_now from salaries where to_date='9999-01-01') as tb1join (select e.emp_no ,salary as salary_start from employees e join salaries s on e.emp_no=s.emp_no where from_date=hire_date) as tb2on tb1.emp_no=tb2.emp_noorder by growth;
select d.dept_no,dept_name,count(s.from_date) as sum from departments djoin dept_emp de on d.dept_no=de.dept_nojoin salaries s on de.emp_no=s.emp_nogroup by d.dept_no;
select s1.emp_no,s1.salary,count(distinct s2.salary) as rankfrom salaries s1,salaries s2where s1.to_date='9999-01-01' and s2.to_date='9999-01-01' and s1.salary<=s2.salarygroup by s1.emp_noorder by s1.salary desc,s1.emp_no asc;
select emp_tb.emp_no,manager_no,emp_tb.salary,manager_tb.salaryfrom(select de.emp_no,dept_no,salary from dept_emp de join salaries s on de.emp_no=s.emp_no where de.to_date='9999-01-01' and s.to_date='9999-01-01') as emp_tbjoin (select dm.emp_no as manager_no,dept_no,salary from dept_manager dm join salaries s on dm.emp_no=s.emp_no where dm.to_date='9999-01-01' and s.to_date='9999-01-01') as manager_tbon emp_tb.dept_no=manager_tb.dept_no and emp_tb.salary>manager_tb.salary;
select d.dept_no,dept_name,title,count(title) as count from departments djoin dept_emp de on d.dept_no=de.dept_nojoin titles t on de.emp_no=t.emp_nowhere de.to_date='9999-01-01' and t.to_date='9999-01-01'group by d.dept_no,title;
select s1.emp_no,s1.from_date,(s1.salary-s2.salary) as salary_growthfrom salaries s1,salaries s2where s1.emp_no=s2.emp_no and salary_growth>5000 and (strftime('%Y',s1.to_date)-strftime('%Y',s2.to_date)=1 or strftime('%Y',s1.from_date)-strftime('%Y',s2.from_date)=1)order by salary_growth desc;
select avg(salary) as avg_salary from salaries where salary not in (select max(salary) from salaries) and salary not in (select min(salary) from salaries) and to_date='9999-01-01';
select first_name from employees order by substr(first_name,length(first_name)-1);
select dept_no,group_concat(emp_no) as employeesfrom dept_emp group by dept_no;
-- 方法1/*select * from employees where not exists (select emp_no from dept_emp where emp_no = employees.emp_no);*/-- 方法2select * from employees where emp_no not in (select emp_no from dept_emp);
select e.emp_no,first_name,last_name,eb.btype,salary,(case when btype=1 then 0.1*salary when btype=2 then 0.2*salary else 0.3*salary end)as bonusfrom employees e,salaries s,emp_bonus ebwhere e.emp_no=s.emp_no and e.emp_no=eb.emp_no and s.to_date='9999-01-01';
select s1.emp_no,s1.salary,(select sum(s2.salary) from salaries s2 where s2.emp_no<=s1.emp_no and s2.to_date='9999-01-01') as running_totalfrom salaries s1 where s1.to_date='9999-01-01'order by s1.emp_no;
select e1.first_name from employees e1where (select count(*) from employees e2 where e1.first_name<=e2.first_name)%2=1;
这些题都是很常见的SQL题目,但是简短时间内,很难写出,或者容易出错。
转载地址:http://fslrb.baihongyu.com/