SQL(21-40)

文章目录

21. 查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅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`));
select e.emp_no,s1.salary - s2.salary as growth
from employees e inner join salaries s1
on e.emp_no = s1.emp_no and s1.to_date='9999-01-01'
inner join salaries s2
on e.emp_no = s2.emp_no and s2.from_date = e.hire_date
order by growth ASC

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`));
select d.dept_no,d.dept_name,count(*) as sum
from departments d inner join dept_emp de
on d.dept_no = de.dept_no
inner join salaries s
on de.emp_no = s.emp_no
group by 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`));

链接:https://www.nowcoder.com/questionTerminal/b9068bfe5df74276bd015b9729eec4bf
来源:牛客网

  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)) as Rank
from salaries s1 inner join salaries s2
on 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,s1.emp_no asc

最后在支持ROW_NUMBER、RANK、DENSE_RANK等函数的SQL Server数据库中,有以下参考代码,可惜在本题的SQLite数据库中不支持。

SELECT emp_no, salaries, DENSE_RANK() OVER(ORDER BY salary DESC) AS rank
WHERE to_date = '9999-01-01' ORDER BY salary DESC, emp_no ASC

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 de.dept_no, e.emp_no, s.salary
from employees e inner join dept_emp de
on e.emp_no = de.emp_no 
inner join salaries s
on e.emp_no = s.emp_no where s.to_date='9999-01-01'
and e.emp_no not in (
select emp_no from dept_manager
where to_date='9999-01-01')

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  
de.emp_no, dm.emp_no as manager_no, 
s1.salary as emp_salary,s2.salary as manager_salary
from dept_emp de inner join dept_manager dm 
on de.dept_no = dm.dept_no 
inner join salaries s1 
on de.emp_no = s1.emp_no and s1.to_date='9999-01-01'
inner join salaries s2 
on dm.emp_no = s2.emp_no and s2.to_date='9999-01-01'
and s1.salary>s2.salary
select  
t1.emp_no, t2.emp_no as manager_no, 
t1.salary as emp_salary,t2.salary as manager_salary
from
(select de.emp_no ,de.dept_no, s.salary 
from dept_emp de inner join salaries s 
on de.emp_no = s.emp_no and s.to_date='9999-01-01')t1
inner join (
select dm.emp_no , dm.dept_no,s.salary 
from dept_manager dm inner join salaries s 
on dm.emp_no = s.emp_no and s.to_date='9999-01-01'
)t2
on t1.dept_no = t2.dept_no and t1.salary>t2.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 d.dept_no,d.dept_name,t.title,count(de.emp_no) as count
from departments d inner join dept_emp de
on d.dept_no = de.dept_no and de.to_date='9999-01-01'
inner join titles t
on de.emp_no = t.emp_no and t.to_date='9999-01-01'
group by d.dept_no,t.title

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 s1,salaries 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

28. 查找描述信息中包括robot的电影对应的分类名称以及电影数目,而且还需要该分类对应电影数量>=5部

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));
CREATE TABLE category  (
category_id  tinyint(3)  NOT NULL ,
name  varchar(25) NOT NULL, `last_update` timestamp,
PRIMARY KEY ( category_id ));
CREATE TABLE film_category  (
film_id  smallint(5)  NOT NULL,
category_id  tinyint(3)  NOT NULL, `last_update` timestamp);

题目太坑人,有两个统计量要注意,一个数量是帅选category_id的,category_id下的所有电影数量>=5,另一个数量是电影描述中包括robot的各类别下的电影数量

select c.name,count(f.film_id) as amount
from film f inner join film_category fc
on f.film_id = fc.film_id and f.description like '%robot%'
inner join (
select count(category_id) as amount,category_id
from film_category  
group by category_id
having amount>=5
)fcc on fcc.category_id = fc.category_id
inner join category  c
on fc.category_id = c.category_id
group by c.name

29. 使用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

30. 使用子查询的方式找出属于Action分类的所有电影对应的title,description

select f.title,f.description
from film f inner join film_category fc
on f.film_id = fc.film_id
inner join category c
on fc.category_id = c.category_id and c.name='Action'

32. 获取select * from employees对应的执行计划

explain select * from employees

32. 将employees表的所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分

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

不同数据库连接字符串的方法不完全相同,MySQL、SQL Server、Oracle等数据库支持CONCAT方法,而本题所用的SQLite数据库只支持用连接符号"||"来连接字符串

select concat(last_name,' ',first_name) as Name
from employees
select last_name||' '||first_name as Name
from employees

33. 创建一个actor表,包含如下列信息

列表 类型 是否为NULL 含义
actor_id smallint(5) not null 主键id
first_name varchar(45) not null 名字
last_name varchar(45) not null 姓氏
last_update timestamp not null 最后更新时间,默认是系统的当前时间
create table if not exists 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'))
)

34. 对于表actor批量插入如下数据

CREATE TABLE IF NOT EXISTS 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')))
actor_id first_name last_name last_update
1 PENELOPE GUINESS 2006-02-15 12:34:33
2 NICK WAHLBERG 2006-02-15 12:34:33
INSERT INTO actor
SELECT 1, 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'
UNION SELECT 2, 'NICK', 'WAHLBERG', '2006-02-15 12:34:33'
INSERT INTO actor
VALUES (1, 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'),
(2, 'NICK', 'WAHLBERG', '2006-02-15 12:34:33')

35. 对于表actor批量插入如下数据,如果数据已经存在,请忽略,不使用replace操作

CREATE TABLE IF NOT EXISTS 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')))
insert or ignore into actor values('3','ED','CHASE','2006-02-15 12:34:33')

36. 创建actor_name表

对于如下表actor,其对应的数据为:

actor_id first_name last_name last_update
1 PENELOPE GUINESS 2006-02-15 12:34:33
2 NICK WAHLBERG 2006-02-15 12:34:33

创建一个actor_name表,将actor表中的所有first_name以及last_name导入改表。 actor_name表结构如下:

列表 类型 是否为NULL 含义
first_name varchar(45) not null 名字
last_name varchar(45) not null 姓氏
create table actor_name (
    first_name varchar(45) not null,
    last_name varchar(45) not null
);
insert into actor_name(first_name,last_name) select first_name,last_name from actor;

题目使用的是sqlite3,可以这么做:

create table actor_name as
select first_name,last_name from actor;

如果是mysql,那么as可以去掉,也可以不去掉,例如:

create table actor_name
select first_name,last_name from actor;

37. 针对如下表actor结构创建索引:

CREATE TABLE IF NOT EXISTS 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')))

对first_name创建唯一索引uniq_idx_firstname,对last_name创建普通索引idx_lastname

create unique index uniq_idx_firstname on actor(first_name);
create index idx_lastname on actor(last_name);

38. 针对actor表创建视图actor_name_view,只包含first_name以及last_name两列,并对这两列重新命名,first_name为first_name_v,last_name修改为last_name_v:

CREATE TABLE IF NOT EXISTS 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')))

链接:https://www.nowcoder.com/questionTerminal/b9db784b5e3d488cbd30bd78fdb2a862
来源:牛客网

注意 CREATE VIEW … AS … 的 AS 是创建视图语法中的一部分,而后面的两个 AS 只是为字段创建别名

CREATE VIEW actor_name_view AS
SELECT first_name AS first_name_v, last_name AS last_name_v
FROM actor

方法二:直接在视图名的后面用小括号创建视图中的字段名

CREATE VIEW actor_name_view (first_name_v, last_name_v) AS
SELECT first_name, last_name FROM actor

39. 针对salaries表emp_no字段创建索引idx_emp_no,查询emp_no为10005, 使用强制索引。

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 index idx_emp_no on salaries(emp_no);
select * from salaries indexed by idx_emp_no where emp_no='10005'

40.增加列

存在actor表,包含如下列信息:

CREATE TABLE IF NOT EXISTS 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')));

现在在last_update后面新增加一列名字为create_date, 类型为datetime, NOT NULL,默认值为’0000 00:00:00’

alter table actor add column create_date datetime not null default '0000-00-00 00:00:00'

猜你喜欢

转载自blog.csdn.net/weixin_42933718/article/details/88925802
今日推荐