牛客网在线编程网址:https://www.nowcoder.com/activity/oj

(默认使用SQLite)

 

题目1:

按照dept_no进行汇总,属于同一个部门的emp_no按照逗号进行连接,结果给出dept_no以及连接出的结果employees

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`));

用group_concat函数

select dept_no, group_concat(emp_no, ',') employees 
from dept_emp
group by dept_no
order by dept_no;

 

题目2:

查找排除当前最大、最小salary之后的员工的平均工资avg_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`));
select avg(salary) as avg_salary from salaries
where to_date = '9999-01-01'
AND salary <> (select max(salary) from salaries)
AND salary <> (select min(salary) from salaries);

实际子查询应该也要考虑最大最小salary是否是当前的,不过这样就通不过了:

select avg(salary) as avg_salary from salaries
where to_date = '9999-01-01'
AND salary <> (select max(salary) from salaries where to_date = '9999-01-01')
AND salary <> (select min(salary) from salaries where to_date = '9999-01-01');

 

题目3:

分页查询employees表,每5行一页,返回第2页的数据

select * from employees limit 5,5;
/*select * from employees limit 5 offset 5;*/

 

题目4:

获取所有员工的emp_no、部门编号dept_no以及对应的bonus类型btype和recevied,没有分配具体的员工不显示

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`));
create table emp_bonus(
emp_no int not null,
recevied datetime not null,
btype smallint not null);

用left join,没有分配到bonus的员工就不会显示后两个字段的信息了:

select dept_emp.emp_no, dept_emp.dept_no, EB.btype, EB.recevied
FROM dept_emp LEFT JOIN emp_bonus EB
ON dept_emp.emp_no = EB.emp_no;

 

题目5:

使用含有关键字exists查找未分配具体部门的员工的所有信息。

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 `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`));

如下

select * from employees
where not exists (select emp_no from dept_emp where emp_no = employees.emp_no);

https://www.techonthenet.com/sqlite/exists.php

Note

  • SQL statements that use the EXISTS Condition in SQLite are very inefficient since the sub-query is RE-RUN for EVERY row in the outer query's table. There are more efficient ways to write most queries, that do not use the EXISTS Condition.

之所以是这个结果,是因为每次外表都是读入一行去执行子查询是否满足的条件。但这种方法也因此比较没有效率,可以通过其他查询来实现目标功能。

 

题目6:

存在如下的视图:

create view emp_v as select * from employees where emp_no >10005;
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中的行数据,且这些行也存在于emp_v中。注意不能使用intersect关键字。

select * from employees 
where emp_no in (select emp_no from emp_v);
select employees.* from employees, emp_v
where employees.emp_no = emp_v.emp_no;
/*或者再添加AND employees.birth_date = emp_v.birth_date等*/

 

题目7:

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 `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 emp_bonus(
emp_no int not null,
recevied datetime not null,
btype smallint not null);
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、first_name、last_name、奖金类型btype、对应的当前薪水情况salary以及奖金金额bonus。 bonus类型btype为1其奖金为薪水salary的10%,btype为2其奖金为薪水的20%,其他类型均为薪水的30%。 当前薪水表示to_date='9999-01-01'。

select emp.emp_no, emp.first_name, emp.last_name, emp_bonus.btype, sal.salary, 
(case emp_bonus.btype
when 1 then sal.salary*0.1
when 2 then sal.salary*0.2
else sal.salary*0.3
end) as bonus
from employees emp, emp_bonus, salaries sal
where emp.emp_no = emp_bonus.emp_no
and emp.emp_no = sal.emp_no
and sal.to_date = '9999-01-01';

 

题目8:

按照salary的累计和running_total,其中running_total为前两个员工的salary累计和,其他以此类推。 具体结果如下Demo展示。

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_nosalaryrunning_total
10001 88958 88958
10002 72527 161485
10003 43311 204796
10004 74057 278853
10005 94692 373545
select s1.emp_no, s1.salary, sum(s2.salary) running_total
from salaries s1 INNER JOIN salaries s2 
ON s1.emp_no >= s2.emp_no
and s1.to_date = '9999-01-01'
and s2.to_date = '9999-01-01'
group by s1.emp_no
order by s1.emp_no;

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_total
from salaries s1
where s1.to_date = '9999-01-01'
order by s1.emp_no;

 

题目9:

对于employees表中,给出奇数行的first_name

 (隐含的意思应该是按first_name排序后的奇数行,但输出结果不用做排序)

select first_name from
(
    select first_name, (select count(*) from employees e2 where e2.first_name <= e1.first_name) as rank 
    from employees e1
) as temp
where temp.rank%2 <> 0;  /*rank整除2取余不为零 奇数*/

更简练的:

select first_name 
from employees s1
where (select count(*) from employees s2 where s2.first_name <= s1.first_name)%2 <> 0;

 

posted on 2017-11-14 11:50  RRRRecord  阅读(665)  评论(0编辑  收藏  举报