1.查找最晚入职员工的所有信息
建表语句:
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里最晚入职员工的所有信息
SQL语句如下:
SELECT
*
FROM employees
where
hire_date = (SELECT MAX(hire_date) from employees)
2.查找employees里入职员工时间排名倒数第三的员工所有信息
简单:请你查找employees里入职员工时间排名倒数第三的员工所有信息
SQL语句如下:
SELECT
*
FROM employees
ORDER BY hire_date DESC LIMIT 2,1
limit解释
limit子句用于限制查询结果返回的数量。
用法:【select * from tableName limit i,n 】
参数:
tableName : 为数据表;
i : 为查询结果的索引值(默认从0开始);
n : 为查询结果返回的数量
3.查找所有已经分配部门的员工的last_name和first_name以及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`));
简单:请你查找所有已经分配部门的员工的last_name和first_name以及dept_no,未分配的部门的员工不显示
SQL语句如下:
#1
# select last_name, first_name, dept_no
# from dept_emp as d, employees as e where d.emp_no = e.emp_no
#2
SELECT E.last_name,E.first_name,D.DEPT_NO
FROM employees E
JOIN dept_emp D ON E.emp_no=D.emp_no
4.查找薪水变动超过15次的员工号emp_no以及其对应的变动次数t
薪水表
建表语句:
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`));
简单:请你查找薪水变动超过15次的员工号emp_no以及其对应的变动次数t,以上例子输出如下
SQL语句如下:
select emp_no, count(to_date) as t
from salaries group by emp_no having t > 15
having解释
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用。
指定组或聚合的搜索条件。HAVING 只能与 SELECT 语句一起使用。HAVING 通常在 GROUP BY 子句中使用。如果不使用 GROUP BY 子句,则 HAVING 的行为与 WHERE 子句一样。
语法
[ HAVING <search condition> ]
参数
<search_condition>
指定组或聚合应满足的搜索条件。当 HAVING 与 GROUP BY ALL 一起使用时,HAVING 子句优于 ALL。
在 HAVING 子句中不能使用 text、image 和 ntext 数据类型。
在 SELECT 语句中使用 HAVING 子句不影响 CUBE 运算符分组结果集和返回汇总聚合行的方式。
5.找出所有员工当前薪水salary情况
请你找出所有员工具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示,以上例子输出如下:
SQL语句如下:
select distinct salary
from salaries
order by salary desc
6.获取所有非manager的员工emp_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`));
简单:请你找出所有非部门领导的员工emp_no,以上例子输出:
SQL语句如下:
select emp_no
from employees
where emp_no not in
(select emp_no from dept_manager)
7.查找employees表
简单:请你查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列,以上例子查询结果如下:
SQL语句如下:
select * from employees
where emp_no % 2 = 1 and last_name != 'Mary'
order by hire_date desc
8.获取当前薪水第二多的员工的emp_no以及其对应的薪水salary
简单:请你获取薪水第二多的员工的emp_no以及其对应的薪水salary
SQL语句如下:
select emp_no, salary from salaries
order by salary desc limit 1,1
9.将employees表的所有员工的last_name和first_name拼接起来作为Name
简单:将employees表的所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分
(注:sqllite,字符串拼接为 || 符号,不支持concat函数,mysql支持concat函数)
SQL语句如下:
select concat(last_name," ",first_name) as name from employees
concat解释
concat()函数
1、功能:将多个字符串连接成一个字符串。
2、语法:concat(str1, str2,...)
返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null
9.删除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');
简单:删除emp_no重复的记录,只保留最小的id对应的记录。
SQL语句如下:
delete from titles_test
where id not in
(
select * from
(select min(id) from titles_test group by emp_no) as t
)
10.将所有to_date为9999-01-01的全部更新为NULL
建表语句:
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');
简单:将所有to_date为9999-01-01的全部更新为NULL,且 from_date更新为2001-01-01
SQL语句如下:
update titles_test
set to_date = NULL, from_date = '2001-01-01'
where to_date = '9999-01-01'
11.将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005
建表语句:
CREATE TABLE 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');
简单:将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005,其他数据保持不变,使用replace实现,直接使用update会报错。
SQL语句如下:
update titles_test
set emp_no = replace(emp_no,10001,10005)
where id = 5
replace解释
replace函数
语法:replace(object,search,replace)
语义:把object对象中出现的的search全部替换成replace。
12.将titles_test表名修改为titles_2017
简单:将titles_test表名修改为titles_2017。
SQL语句如下:
alter table titles_test rename as titles_2017
13.批量插入数据
建表语句:
drop table if exists actor;
CREATE TABLE actor (
actor_id smallint(5) NOT NULL PRIMARY KEY,
first_name varchar(45) NOT NULL,
last_name varchar(45) NOT NULL,
last_update DATETIME NOT NULL)
简单:请你对于表actor批量插入如下数据(不能有2条insert语句哦!)
SQL语句如下:
insert into actor
(actor_id,first_name,last_name,last_update)
values(1,'PENELOPE','GUINESS','2006-02-15 12:34:33'),
(2,'NICK','WAHLBERG','2006-02-15 12:34:33');
14.出现三次以上相同积分的情况
在牛客刷题的小伙伴们都有着牛客积分,积分(grade)表简化可以如下:
简单:id为用户主键id,number代表积分情况,让你写一个sql查询,积分表里面出现三次以及三次以上的积分,查询结果如下:
SQL语句如下:
select number from grade
group by number
having count(number) > 2
15.找到每个人的任务
有一个person表,主键是id,如下:
有一个任务(task)表如下,主键也是id,如下
简单:请你找到每个人的任务情况,并且输出出来,没有任务的也要输出,而且输出结果按照person的id升序排序,输出情况如下
SQL语句如下:
select p.id, p.name,t.content
from person as p left join task as t
on p.id = t.person_id
order by p.id
16.牛客每个人最近的登录日期(一)
牛客每天有很多人登录,请你统计一下牛客每个用户最近登录是哪一天。
有一个登录(login)记录表,简况如下:
第1行表示id为2的用户在2020-10-12使用了客户端id为1的设备登录了牛客网
。。。
第4行表示id为3的用户在2020-10-13使用了客户端id为2的设备登录了牛客网
简单:请你写出一个sql语句查询每个用户最近一天登录的日子,并且按照user_id升序排序,上面的例子查询结果如下:
查询结果表明:
user_id为2的最近的登录日期在2020-10-13
user_id为3的最近的登录日期也是2020-10-13
SQL语句如下:
select user_id, max(date) as d
from login group by user_id
order by user_id
17.考试分数(一)
牛客每次考试完,都会有一个成绩表(grade),如下:
第1行表示用户id为1的用户选择了C++岗位并且考了11001分
。。。
第8行表示用户id为8的用户选择了JS岗位并且考了9999分
简单:请你写一个sql语句查询各个岗位分数的平均数,并且按照分数降序排序,结果保留小数点后面3位(3位之后四舍五入):
(注意: sqlite 1/2得到的不是0.5,得到的是0,只有1*1.0/2才会得到0.5,sqlite四舍五入的函数为round)
SQL语句如下:
select job,round(avg(score),3) as avg
from grade group by job
order by avg desc
round解释
在mysql中,round函数用于数据的四舍五入,它有两种形式:
round(x,d) ,x指要处理的数,d是指保留几位小数
这里有个值得注意的地方是,d可以是负数,这时是指定小数点左边的d位整数位为0,同时小数位均为0;