文章目录
- 41. 构造一个触发器audit_log,在向employees_test表中插入一条数据的时候,触发插入相关的数据到audit中。
- 42. 删除emp_no重复的记录,只保留最小的id对应的记录。
- 43. 将所有to_date为9999-01-01的全部更新为NULL,且 from_date更新为2001-01-01。
- 44. 将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005,其他数据保持不变,使用replace实现。
- 45.将titles_test表名修改为titles_2017。
- 46 在audit表上创建外键约束,其emp_no对应employees_test表的主键id。
- 47. 如何获取emp_v和employees有相同的数据?
- 48.将所有获取奖金的员工当前的薪水增加10%。
- 49. 针对库中的所有表生成select count(*)对应的SQL语句
- 50. 查找字符串'10,A,B' 中逗号','出现的次数cnt。
- 51.获取Employees中的first_name,查询按照first_name最后两个字母,按照升序进行排列
- 52. 按照dept_no进行汇总,属于同一个部门的emp_no按照逗号进行连接,结果给出dept_no以及连接出的结果employees
- 53.查找排除当前最大、最小salary之后的员工的平均工资avg_salary。
- 54. 分页查询employees表,每5行一页,返回第2页的数据
- 55. 使用含有关键字exists查找未分配具体部门的员工的所有信息。
- 56. 给出emp_no、first_name、last_name、奖金类型btype、对应的当前薪水情况salary以及奖金金额bonus。 bonus类型btype为1其奖金为薪水salary的10%,btype为2其奖金为薪水的20%,其他类型均为薪水的30%。 当前薪水表示to_date='9999-01-01'
- 57. 按照salary的累计和running_total,其中running_total为前两个员工的salary累计和,其他以此类推。
- 58. 对于employees表中,给出奇数行的first_name
41. 构造一个触发器audit_log,在向employees_test表中插入一条数据的时候,触发插入相关的数据到audit中。
CREATE TABLE employees_test(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
CREATE TABLE audit(
EMP_no INT NOT NULL,
NAME TEXT NOT NULL
);
create trigger audit_log after insert on employees_test
begin
insert into audit values(new.id,new.name);
end
42. 删除emp_no重复的记录,只保留最小的id对应的记录。
CREATE TABLE IF NOT EXISTS titles_test (
id int(11) not null primary key,
emp_no int(11) NOT NULL,
title varchar(50) NOT NULL,
from_date date NOT NULL,
to_date date DEFAULT NULL);
insert into titles_test values ('1', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('2', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('3', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('4', '10004', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('5', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('6', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('7', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01');
delete from titles_test
where id not in (
select min(id) from titles_test
group by emp_no
)
43. 将所有to_date为9999-01-01的全部更新为NULL,且 from_date更新为2001-01-01。
CREATE TABLE IF NOT EXISTS titles_test (
id int(11) not null primary key,
emp_no int(11) NOT NULL,
title varchar(50) NOT NULL,
from_date date NOT NULL,
to_date date DEFAULT NULL);
insert into titles_test values ('1', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('2', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('3', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('4', '10004', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('5', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('6', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('7', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01');
update titles_test set to_date=null,from_date='2001-01-01'
where to_date='9999-01-01'
44. 将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005,其他数据保持不变,使用replace实现。
CREATE TABLE IF NOT EXISTS titles_test (
id int(11) not null primary key,
emp_no int(11) NOT NULL,
title varchar(50) NOT NULL,
from_date date NOT NULL,
to_date date DEFAULT NULL);
insert into titles_test values ('1', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('2', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('3', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('4', '10004', 'Senior Engineer', '1995-12-03', '9999-01-01'),
('5', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
('6', '10002', 'Staff', '1996-08-03', '9999-01-01'),
('7', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01');
replace into titles_test
values('5', '10005', 'Senior Engineer', '1986-06-26', '9999-01-01')
45.将titles_test表名修改为titles_2017。
alter table titles_test rename to titles_2017;
46 在audit表上创建外键约束,其emp_no对应employees_test表的主键id。
CREATE TABLE employees_test(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
CREATE TABLE audit(
EMP_no INT NOT NULL,
create_date datetime NOT NULL
);
链接:https://www.nowcoder.com/questionTerminal/aeaa116185f24f209ca4fa40e226de48
来源:牛客网
drop table audit;
CREATE TABLE audit(
EMP_no INT NOT NULL,
create_date datetime NOT NULL,
FOREIGN KEY(EMP_no) REFERENCES employees_test(ID));
真是一个大坑。总结下,MySQL下,可以直接使用如下语句 修改:
alter table audit
add foreign key(emp_no) references employees_test(id)
47. 如何获取emp_v和employees有相同的数据?
存在如下的视图:
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`));
链接:https://www.nowcoder.com/questionTerminal/2435cc7b43c94d3b88ffbcfadc0241de
来源:牛客网
方法一:用 WHERE 选取二者 emp_no 相等的记录
1
SELECT em.* FROM employees AS em, emp_v AS ev WHERE em.emp_no = ev.emp_no
方法二:用 INTERSECT 关键字求 employees 和 emp_v 的交集
可参考:http://www.sqlite.org/lang_select.html
SELECT * FROM employees INTERSECT SELECT * FROM emp_v
方法三:仔细一想,emp_v的全部记录均由 employees 导出,因此可以投机取巧,直接输出 emp_v 所有记录
SELECT * FROM emp_v
48.将所有获取奖金的员工当前的薪水增加10%。
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`));
update salaries set salary = 1.1 * salary
where emp_no in(
select s.emp_no
from salaries s inner join emp_bonus eb
on s.emp_no = eb.emp_no
where eb.recevied is not null
and s.to_date = '9999-01-01' )
49. 针对库中的所有表生成select count(*)对应的SQL语句
mysql
SELECT concat("select count(*) from ",new.table_name,";") AS cnts
FROM (
SELECT table_name FROM information_schema.columns WHERE table_schema = 'sqlite_master') AS new;
SQLite 中用 “||” 符号连接字符串
SELECT "select count(*) from " || name || ";" AS cnts
FROM sqlite_master WHERE type = 'table'
50. 查找字符串’10,A,B’ 中逗号’,'出现的次数cnt。
select (length('10,A,B' )-length(replace('10,A,B',",",""))) as cnt;
51.获取Employees中的first_name,查询按照first_name最后两个字母,按照升序进行排列
select first_name
from employees
order by substr(first_name,length(first_name)-1);
52. 按照dept_no进行汇总,属于同一个部门的emp_no按照逗号进行连接,结果给出dept_no以及连接出的结果employees
select dept_no,group_concat(emp_no) as employees
from dept_emp
group by dept_no
53.查找排除当前最大、最小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 salary not in (
select max(salary) from salaries
)
and salary not in(
select min(salary) from salaries
)
and to_date = '9999-01-01'
54. 分页查询employees表,每5行一页,返回第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`));
方法一:利用 LIMIT 和 OFFSET 关键字。LIMIT 后的数字代表返回几条记录,OFFSET 后的数字代表从第几条记录开始返回(第一条记录序号为0),也可理解为跳过多少条记录后开始返回。
1
SELECT * FROM employees LIMIT 5 OFFSET 5
方法二:只利用 LIMIT 关键字。注意:在 LIMIT X,Y 中,Y代表返回几条记录,X代表从第几条记录开始返回(第一条记录序号为0),切勿记反。
1
SELECT * FROM employees LIMIT 5,5
55. 使用含有关键字exists查找未分配具体部门的员工的所有信息。
elect * from employees
where not exists(
select emp_no from dept_emp
where emp_no = employees.emp_no
)
56. 给出emp_no、first_name、last_name、奖金类型btype、对应的当前薪水情况salary以及奖金金额bonus。 bonus类型btype为1其奖金为薪水salary的10%,btype为2其奖金为薪水的20%,其他类型均为薪水的30%。 当前薪水表示to_date=‘9999-01-01’
select e.emp_no,e.first_name,e.last_name,eb.btype,s.salary,
(CASE eb.btype
WHEN 1 THEN s.salary * 0.1
WHEN 2 THEN s.salary * 0.2
ELSE s.salary * 0.3 END) AS bonus
from (employees e inner join emp_bonus eb
on e.emp_no = eb.emp_no)
inner join salaries s
on e.emp_no = s.emp_no
and s.to_date = '9999-01-01'
57. 按照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`));
select s1.emp_no,s1.salary,(select sum(s2.salary)
from salaries as s2
where s2.emp_no<=s1.emp_no
and s2.to_date = '9999-01-01') as running_total
from salaries as s1
where s1.to_date = '9999-01-01'
select s1.emp_no,s1.salary,sum(s2.salary) as running_total
from salaries s1 inner join salaries s2
on s2.emp_no<=s1.emp_no
where s2.to_date = '9999-01-01'
and s1.to_date = '9999-01-01'
group by s1.emp_no
58. 对于employees表中,给出奇数行的first_name
SELECT e1.first_name FROM
employees e1
WHERE
(SELECT count(*) FROM employees e2
WHERE e1.first_name <=e2.first_name)%2=1;