SQL(41-58)

文章目录

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;

猜你喜欢

转载自blog.csdn.net/weixin_42933718/article/details/88925826
41
58
41A