获取当前薪水第二多的员工的emp_no以及其对应的薪水salary

请你查找薪水排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不能使用order by完成,以上例子输出为:
(温馨提示:
  sqlite通过的代码不一定能通过mysql,因为SQL语法规定,使用聚合函数时,
  select子句中一般只能存在以下三种元素:常数、聚合函数,group by 指定的列名。
  如果使用非group by的列名,sqlite的结果和mysql 可能不一样
)
drop table if exists  `employees` ;
drop table if exists `salaries` ;
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`));
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01');
INSERT INTO salaries VALUES(10004,74057,'2001-11-27','9999-01-01'); 请你查找薪水排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不能使用order by完成,
以上例子输出为:
(温馨提示:
sqlite通过的代码不一定能通过mysql,因为SQL语法规定,使用聚合函数时,
select子句中一般只能存在以下三种元素:
常数、聚合函数,group by 指定的列名。
如果使用非group by的列名,sqlite的结果和mysql 可能不一样) -- 1、查询最大薪资值
SELECT MAX(`salary`)
FROM `salaries` WHERE
`to_date` = '9999-01-01' -- 2、查询第二大的薪资值
SELECT MAX(`salary`)
FROM `salaries`
WHERE
`to_date` = '9999-01-01'
AND `salary` < (
SELECT MAX(`salary`)
FROM `salaries`
WHERE `to_date` = '9999-01-01'
) -- 3、联表查询
SELECT
e.emp_no,
s.salary,
e.last_name,
e.first_name
FROM
employees AS e
LEFT JOIN salaries AS s ON e.emp_no = s.emp_no
WHERE
s.salary = (
SELECT MAX(`salary`)
FROM `salaries`
WHERE
`to_date` = '9999-01-01'
AND `salary` < (
SELECT MAX(`salary`)
FROM `salaries`
WHERE `to_date` = '9999-01-01'
)
)

  

对所有员工的薪水按照salary降序进行1-N的排名

所有员工的薪水按照salary降序先进行1-N的排名,如果salary相同,再按照emp_no升序排列

drop table if exists  `salaries` ;
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`));
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01');
INSERT INTO salaries VALUES(10004,72527,'2001-12-01','9999-01-01'); -- MYSQL8版本支持
SELECT
emp_no,
salary,
dense_rank ( ) over ( ORDER BY salary DESC ) AS rank
FROM salaries
WHERE to_date = '9999-01-01'
ORDER BY rank ASC, emp_no ASC; -- MYSQL5支持 rank排名:查询表中大于自己薪水的员工的数量(考虑并列:去重)
SELECT
s1.emp_no,
s1.salary,
(SELECT
COUNT(DISTINCT s2.salary)
FROM salaries s2
WHERE
s2.to_date = '9999-01-01'
AND s2.salary >= s1.salary) AS `rank` -- 去重:计算并列排名
FROM salaries s1
WHERE s1.to_date = '9999-01-01'
ORDER BY
s1.salary DESC,
s1.emp_no ;

  

获取所有非manager员工当前的薪水情况

获取所有非manager员工薪水情况,给出dept_no、emp_no以及salary

drop table if exists  `dept_emp` ;
drop table if exists `dept_manager` ;
drop table if exists `employees` ;
drop table if exists `salaries` ;
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`));
INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01');
INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01');
INSERT INTO dept_manager VALUES('d001',10002,'1996-08-03','9999-01-01');
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1996-08-03');
INSERT INTO salaries VALUES(10001,88958,'1986-06-26','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1996-08-03','9999-01-01'); -- 4表连接
SELECT
D.dept_no,
E.emp_no,
S.salary
FROM
employees AS E
LEFT JOIN dept_manager AS MGR ON E.emp_no = MGR.emp_no
LEFT JOIN salaries AS S ON E.emp_no = S.emp_no
LEFT JOIN dept_emp AS D ON E.emp_no = D.emp_no
WHERE
MGR.dept_no IS NULL

  

获取有奖金的员工相关信息。

其中bonus类型btype为1其奖金为薪水salary的10%,btype为2其奖金为薪水的20%,其他类型均为薪水的30%。

to_date='9999-01-01'表示当前薪水。

请你给出emp_no、first_name、last_name、奖金类型btype、对应的当前薪水情况salary以及奖金金额bonus。

bonus结果保留一位小数,输出结果按emp_no升序排序。

drop table if exists  `employees` ;
drop table if exists emp_bonus;
drop table if exists `salaries` ;
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 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`));
insert into emp_bonus values
(10001, '2010-01-01',1),
(10002, '2010-10-01',2);
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21'); INSERT INTO salaries VALUES(10001,60117,'1986-06-26','1987-06-26');
INSERT INTO salaries VALUES(10001,62102,'1987-06-26','1988-06-25');
INSERT INTO salaries VALUES(10001,66074,'1988-06-25','1989-06-25');
INSERT INTO salaries VALUES(10001,66596,'1989-06-25','1990-06-25');
INSERT INTO salaries VALUES(10001,66961,'1990-06-25','1991-06-25');
INSERT INTO salaries VALUES(10001,71046,'1991-06-25','1992-06-24');
INSERT INTO salaries VALUES(10001,74333,'1992-06-24','1993-06-24');
INSERT INTO salaries VALUES(10001,75286,'1993-06-24','1994-06-24');
INSERT INTO salaries VALUES(10001,75994,'1994-06-24','1995-06-24');
INSERT INTO salaries VALUES(10001,76884,'1995-06-24','1996-06-23');
INSERT INTO salaries VALUES(10001,80013,'1996-06-23','1997-06-23');
INSERT INTO salaries VALUES(10001,81025,'1997-06-23','1998-06-23');
INSERT INTO salaries VALUES(10001,81097,'1998-06-23','1999-06-23');
INSERT INTO salaries VALUES(10001,84917,'1999-06-23','2000-06-22');
INSERT INTO salaries VALUES(10001,85112,'2000-06-22','2001-06-22');
INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1996-08-03','1997-08-03');
INSERT INTO salaries VALUES(10002,72527,'1997-08-03','1998-08-03');
INSERT INTO salaries VALUES(10002,72527,'1998-08-03','1999-08-03');
INSERT INTO salaries VALUES(10002,72527,'1999-08-03','2000-08-02');
INSERT INTO salaries VALUES(10002,72527,'2000-08-02','2001-08-02');
INSERT INTO salaries VALUES(10002,72527,'2001-08-02','9999-01-01'); -- 主要是考察CASE WHEN 语法
SELECT
E.emp_no,
E.first_name,
E.last_name,
B.btype,
S.salary,
(
CASE B.btype
WHEN 1 THEN ROUND(S.salary * 0.1, 4)
WHEN 2 THEN ROUND(S.salary * 0.2, 4)
ELSE ROUND(S.salary * 0.3, 4)
END
) AS bonus
FROM
employees AS E
LEFT JOIN salaries AS S ON E.emp_no = S.emp_no
LEFT JOIN emp_bonus AS B ON E.emp_no = B.emp_no
WHERE
S.to_date = '9999-01-01'
ORDER BY E.emp_no ASC

  

统计salary的累计和running_total

按照salary的累计和running_total,

其中running_total为前N个当前( to_date = '9999-01-01')员工的salary累计和,其他以此类推。

drop table if exists  `salaries` ;
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`));
INSERT INTO salaries VALUES(10001,60117,'1986-06-26','1987-06-26');
INSERT INTO salaries VALUES(10001,62102,'1987-06-26','1988-06-25');
INSERT INTO salaries VALUES(10001,66074,'1988-06-25','1989-06-25');
INSERT INTO salaries VALUES(10001,66596,'1989-06-25','1990-06-25');
INSERT INTO salaries VALUES(10001,66961,'1990-06-25','1991-06-25');
INSERT INTO salaries VALUES(10001,71046,'1991-06-25','1992-06-24');
INSERT INTO salaries VALUES(10001,74333,'1992-06-24','1993-06-24');
INSERT INTO salaries VALUES(10001,75286,'1993-06-24','1994-06-24');
INSERT INTO salaries VALUES(10001,75994,'1994-06-24','1995-06-24');
INSERT INTO salaries VALUES(10001,76884,'1995-06-24','1996-06-23');
INSERT INTO salaries VALUES(10001,80013,'1996-06-23','1997-06-23');
INSERT INTO salaries VALUES(10001,81025,'1997-06-23','1998-06-23');
INSERT INTO salaries VALUES(10001,81097,'1998-06-23','1999-06-23');
INSERT INTO salaries VALUES(10001,84917,'1999-06-23','2000-06-22');
INSERT INTO salaries VALUES(10001,85112,'2000-06-22','2001-06-22');
INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1996-08-03','1997-08-03');
INSERT INTO salaries VALUES(10002,72527,'1997-08-03','1998-08-03');
INSERT INTO salaries VALUES(10002,72527,'1998-08-03','1999-08-03');
INSERT INTO salaries VALUES(10002,72527,'1999-08-03','2000-08-02');
INSERT INTO salaries VALUES(10002,72527,'2000-08-02','2001-08-02');
INSERT INTO salaries VALUES(10002,72527,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10003,40006,'1995-12-03','1996-12-02');
INSERT INTO salaries VALUES(10003,43616,'1996-12-02','1997-12-02');
INSERT INTO salaries VALUES(10003,43466,'1997-12-02','1998-12-02');
INSERT INTO salaries VALUES(10003,43636,'1998-12-02','1999-12-02');
INSERT INTO salaries VALUES(10003,43478,'1999-12-02','2000-12-01');
INSERT INTO salaries VALUES(10003,43699,'2000-12-01','2001-12-01');
INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01'); -- 查询running_total为前N个当前( to_date = '9999-01-01')员工的salary累计
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'
ORDER BY s1.emp_no

  

给出employees表中排名为奇数行的first_name

drop table if exists  `employees` ;
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`));
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12');
INSERT INTO employees VALUES(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02'); -- 主要实现SQL1 - MYSQL8开窗函数实现
SELECT
first_name,
row_number ( ) over ( ORDER BY first_name ) AS rank_num
FROM employees -- 主要实现SQL1 - 不使用MYSQL8开窗函数,设置变量实现
SET @orderId = 0;
SELECT
first_name,
@orderId:= @orderId + 1 AS `rank`
FROM `employees`
ORDER BY first_name -- 解决SQL:
SELECT E.first_name
FROM
employees AS E JOIN
(
-- 上面两种SQL任选一种作为联表查询
) AS E2 ON E.first_name = E2.first_name
WHERE E2.`rank` % 2 = 1; -- 直接子查询嵌套会因为不是原表顺序,答案不符合
SELECT
e.first_name
FROM employees e JOIN
(
SELECT
first_name,
ROW_NUMBER() OVER(ORDER BY first_name ASC) AS r_num
FROM employees
) AS t
ON e.first_name = t.first_name
WHERE t.r_num % 2 = 1;

  

异常的邮件概率

每一个日期里面,正常用户发送给正常用户邮件失败的概率是多少,

结果保留到小数点后面3位(3位之后的四舍五入),并且按照日期升序排序

drop table if exists email;
drop table if exists user;
CREATE TABLE `email` (
`id` int(4) NOT NULL,
`send_id` int(4) NOT NULL,
`receive_id` int(4) NOT NULL,
`type` varchar(32) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)); CREATE TABLE `user` (
`id` int(4) NOT NULL,
`is_blacklist` int(4) NOT NULL,
PRIMARY KEY (`id`)); INSERT INTO email VALUES
(1,2,3,'completed','2020-01-11'),
(2,1,3,'completed','2020-01-11'),
(3,1,4,'no_completed','2020-01-11'),
(4,3,1,'completed','2020-01-12'),
(5,3,4,'completed','2020-01-12'),
(6,4,1,'completed','2020-01-12'); INSERT INTO user VALUES
(1,0),
(2,1),
(3,0),
(4,0); -- 1、联表实现筛选白名单用户
SELECT
`email`.*
FROM
`email`
JOIN `user` AS u1 ON ( email.send_id = u1.id AND u1.is_blacklist = 0 )
JOIN `user` AS u2 ON ( email.receive_id = u2.id AND u2.is_blacklist = 0 ) -- 2、子查询实现筛选
-- 查询黑名单用户,或者正常用户
SELECT id FROM `user` WHERE `is_blacklist` = 1 -- 在EMAIL表中筛选正常用户来往的邮件记录
SELECT
`email`.*
FROM
`email`
WHERE
email.send_id NOT IN (SELECT id FROM `user` WHERE `is_blacklist` = 1)
AND email.receive_id NOT IN (SELECT id FROM `user` WHERE `is_blacklist` = 1) -- 3、按日期分组进行筛选,直接计数异常次数和总次数即可实现
SELECT
`email`.date,
SUM(`email`.type = 'no_completed' ) AS `异常次数`,
COUNT(`email`.type) AS `总计次数`,
ROUND (SUM(`email`.type = 'no_completed' ) * 1.0 / COUNT(`email`.type), 3 )AS `概率`
FROM
`email`
WHERE
email.send_id NOT IN (SELECT id FROM `user` WHERE `is_blacklist` = 1)
AND email.receive_id NOT IN (SELECT id FROM `user` WHERE `is_blacklist` = 1)
GROUP BY `email`.date
ORDER BY `email`.date -- 最终SQL
SELECT
`email`.date,
ROUND (SUM(`email`.type = 'no_completed' ) * 1.0 / COUNT(`email`.type), 3 )AS `p`
FROM
`email`
WHERE
email.send_id NOT IN (SELECT id FROM `user` WHERE `is_blacklist` = 1)
AND email.receive_id NOT IN (SELECT id FROM `user` WHERE `is_blacklist` = 1)
GROUP BY `email`.date
ORDER BY `email`.date -- 或者按非异常次数查询
SELECT
`email`.date,
SUM( CASE `email`.type WHEN 'completed' THEN 0 ELSE 1 END ) AS `总计`,
COUNT(`email`.type) AS `次数`,
ROUND (SUM( CASE `email`.type WHEN 'completed' THEN 0 ELSE 1 END ) * 1.0 / COUNT(`email`.type), 3 )AS `概率`
FROM
`email`
WHERE
email.send_id NOT IN (SELECT id FROM `user` WHERE `is_blacklist` = 1)
AND email.receive_id NOT IN (SELECT id FROM `user` WHERE `is_blacklist` = 1)
GROUP BY `email`.date
ORDER BY `email`.date

  

 

牛客每个人最近的登录日期(二)

查询每个用户最近一天登录的日子,用户的名字,以及用户用的设备的名字,

并且查询结果按照user的name升序排序

drop table if exists login;
drop table if exists user;
drop table if exists client;
CREATE TABLE `login` (
`id` int(4) NOT NULL,
`user_id` int(4) NOT NULL,
`client_id` int(4) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)); CREATE TABLE `user` (
`id` int(4) NOT NULL,
`name` varchar(32) NOT NULL,
PRIMARY KEY (`id`)); CREATE TABLE `client` (
`id` int(4) NOT NULL,
`name` varchar(32) NOT NULL,
PRIMARY KEY (`id`)); INSERT INTO login VALUES
(1,2,1,'2020-10-12'),
(2,3,2,'2020-10-12'),
(3,2,2,'2020-10-13'),
(4,3,2,'2020-10-13'); INSERT INTO user VALUES
(1,'tm'),
(2,'fh'),
(3,'wangchao'); INSERT INTO client VALUES
(1,'pc'),
(2,'ios'),
(3,'anroid'),
(4,'h5'); -- 全部连接起来筛选最近日期
SELECT
U.`name`,
C.`name` AS `client`,
L.`date`
FROM
`user` AS U
JOIN login AS L ON U.id = L.user_id
JOIN client AS C ON L.client_id = C.id
WHERE
L.`date` = (SELECT MAX(date) FROM login)
ORDER BY U.`name` ASC

  

牛客每个人最近的登录日期(三)

查询新登录用户次日成功的留存率,即第1天登陆之后,第2天再次登陆的概率,保存小数点后面3位(3位之后的四舍五入)

drop table if exists login;
CREATE TABLE `login` (
`id` int(4) NOT NULL,
`user_id` int(4) NOT NULL,
`client_id` int(4) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)); INSERT INTO login VALUES
(1,2,1,'2020-10-12'),
(2,3,2,'2020-10-12'),
(3,1,2,'2020-10-12'),
(4,2,2,'2020-10-13'),
(5,4,1,'2020-10-13'),
(6,1,2,'2020-10-13'),
(7,1,2,'2020-10-14'); SELECT
round( count( DISTINCT user_id ) * 1.0 / ( SELECT count( DISTINCT user_id ) FROM login ), 3 ) AS `p`
FROM
login
WHERE
( user_id, date ) IN (
SELECT user_id, DATE_ADD( min( date ), INTERVAL 1 DAY )
FROM login
GROUP BY user_id
);

  

牛客每个人最近的登录日期(四)

查询每个日期登录新用户个数,并且查询结果按照日期升序排序

drop table if exists login;
CREATE TABLE `login` (
`id` int(4) NOT NULL,
`user_id` int(4) NOT NULL,
`client_id` int(4) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)); INSERT INTO login VALUES
(1,2,1,'2020-10-12'),
(2,3,2,'2020-10-12'),
(3,1,2,'2020-10-12'),
(4,2,2,'2020-10-13'),
(5,1,2,'2020-10-13'),
(6,3,1,'2020-10-14'),
(7,4,1,'2020-10-14'),
(8,4,1,'2020-10-15'); -- 拿到首次登录用户和时间
SELECT `user_id`, MIN( `date` )
FROM `login`
GROUP BY user_id -- 1、可以对Login表的日期分组,用户和日期可以用IN和上述查询结果进行匹配处理
-- 2、如果匹配成功,表示这个用户是在这个日期是首次登录
-- 3、ELSE NULL 不能写 ELSE 0,因为0就会算一条记录,NULL则不被COUNT函数计数
SELECT
`date`,
COUNT(
DISTINCT
CASE
WHEN ( user_id, date ) IN ( SELECT user_id, min( date ) FROM login GROUP BY user_id ) THEN `user_id`
ELSE NULL
END
) AS `new`
FROM login
GROUP BY `date`
ORDER BY `date` ASC;

  

牛客每个人最近的登录日期(六)

查询刷题信息,包括: 用户的名字,以及截止到某天,累计总共通过了多少题,

并且查询结果先按照日期升序排序,再按照姓名升序排序,有登录却没有刷题的哪一天的数据不需要输出

drop table if exists login;
drop table if exists passing_number;
drop table if exists user;
drop table if exists client;
CREATE TABLE `login` (
`id` int(4) NOT NULL,
`user_id` int(4) NOT NULL,
`client_id` int(4) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)); CREATE TABLE `passing_number` (
`id` int(4) NOT NULL,
`user_id` int(4) NOT NULL,
`number` int(4) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)); CREATE TABLE `user` (
`id` int(4) NOT NULL,
`name` varchar(32) NOT NULL,
PRIMARY KEY (`id`)); INSERT INTO login VALUES
(1,2,1,'2020-10-12'),
(2,3,2,'2020-10-12'),
(3,1,2,'2020-10-12'),
(4,1,3,'2020-10-13'),
(5,3,2,'2020-10-13'); INSERT INTO passing_number VALUES
(1,2,4,'2020-10-12'),
(2,3,1,'2020-10-12'),
(3,1,0,'2020-10-13'),
(4,3,2,'2020-10-13'); INSERT INTO user VALUES
(1,'tm'),
(2,'fh'),
(3,'wangchao'); -- 1、使用开窗函数
SELECT
`name` AS `u_n`,
`date`,
SUM(number) OVER (PARTITION BY `user_id` ORDER BY date) AS `ps_num`
FROM
`passing_number` AS `p`
INNER JOIN `user` ON `user`.`id` = `p`.`user_id`
GROUP BY `date`, `u_n`
ORDER BY `date`, `name` -- 2、自连接实现
SELECT `name` AS u_n,date, p.ps_num
FROM
(
SELECT
p1.user_id,
p1.date,
SUM(p2.number) AS ps_num
FROM
passing_number AS p1,
passing_number AS p2
WHERE
p1.date >= p2.date
AND p1.user_id = p2.user_id
GROUP BY p1.date,p1.user_id
) AS p
JOIN `user` ON `user`.id = p.`user_id`
ORDER BY p.date, `user`.`name`

  

考试分数(三)

找出每个岗位分数排名前2名的用户,得到的结果先按照language的name升序排序,再按照积分降序排序,最后按照grade的id升序排序

完全理解不了解题思路了已经。。。

drop table if exists grade;
drop table if exists language;
CREATE TABLE `grade` (
`id` int(4) NOT NULL,
`language_id` int(4) NOT NULL,
`score` int(4) NOT NULL,
PRIMARY KEY (`id`)); CREATE TABLE `language` (
`id` int(4) NOT NULL,
`name` varchar(32) NOT NULL,
PRIMARY KEY (`id`)); INSERT INTO grade VALUES
(1,1,12000),
(2,1,13000),
(3,2,11000),
(4,2,10000),
(5,3,11000),
(6,1,11000),
(7,2,11000); INSERT INTO language VALUES
(1,'C++'),
(2,'JAVA'),
(3,'Python'); SELECT
g1.id,
l.NAME,
g1.score
FROM
grade g1
JOIN `language` l ON g1.language_id = l.id
WHERE
(
SELECT
count( DISTINCT g2.score )
FROM
grade g2
WHERE
g2.score >= g1.score
AND g1.language_id = g2.language_id
) <= 2
ORDER BY l.NAME, g1.score DESC, g1.id;

考试分数(四)

查询各个岗位分数升序排列之后的中位数位置的范围,并且按job升序排序

drop table if exists grade;
CREATE TABLE grade(
`id` int(4) NOT NULL,
`job` varchar(32) NOT NULL,
`score` int(10) NOT NULL,
PRIMARY KEY (`id`)); INSERT INTO grade VALUES
(1,'C++',11001),
(2,'C++',10000),
(3,'C++',9000),
(4,'Java',12000),
(5,'Java',13000),
(6,'B',12000),
(7,'B',11000),
(8,'B',9999); -- 题解
SELECT job,
FLOOR( (COUNT(1) + 1) / 2) AS 'start',
CEIL( (COUNT(1) + 1) / 2) AS 'end'
FROM grade
GROUP BY job
ORDER BY job;
+------+-------+-----+
| job | start | end |
+------+-------+-----+
| B | 2 | 2 |
| C++ | 2 | 2 |
| Java | 1 | 2 |
+------+-------+-----+
3 rows in set (0.05 sec)

  

牛客的课程订单分析(四)

查询在2025-10-15以后,如果有一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程,那么输出这个用户的user_id,以及满足前面条件的第一次购买成功的C++课程或Java课程或Python课程的日期first_buy_date,以及所有日期里购买成功的C++课程或Java课程或Python课程的次数cnt,并且输出结果按照user_id升序排序

drop table if exists order_info;
CREATE TABLE order_info (
id int(4) NOT NULL,
user_id int(11) NOT NULL,
product_name varchar(256) NOT NULL,
status varchar(32) NOT NULL,
client_id int(4) NOT NULL,
date date NOT NULL,
PRIMARY KEY (id)); INSERT INTO order_info VALUES
(1,557336,'C++','no_completed',1,'2025-10-10'),
(2,230173543,'Python','completed',2,'2025-10-12'),
(3,57,'JS','completed',3,'2025-10-23'),
(4,57,'C++','completed',3,'2025-10-23'),
(5,557336,'Java','completed',1,'2025-10-23'),
(6,57,'Java','completed',1,'2025-10-24'),
(7,557336,'C++','completed',1,'2025-10-25'),
(8,557336,'Python','completed',1,'2025-10-25'); -- 直接分组之后筛选对应条件,取MIN(date) 和 COUNT(product_name)
SELECT
user_id,
MIN(date) AS `first_buy_date`,
COUNT(product_name) AS `cnt`
FROM order_info
WHERE
date > '2025-10-15'
AND STATUS = 'completed'
AND product_name IN ( 'C++', 'Java', 'Python' )
GROUP BY user_id
HAVING COUNT( user_id ) > 1 ;
+---------+----------------+-----+
| user_id | first_buy_date | cnt |
+---------+----------------+-----+
| 57 | 2025-10-23 | 2 |
| 557336 | 2025-10-23 | 3 |
+---------+----------------+-----+
2 rows in set (0.05 sec)

  

牛客的课程订单分析(七)

查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的来源信息,

第一列是显示的是客户端名字,如果是拼团订单则显示GroupBuy,第二列显示这个客户端(或者是拼团订单)有多少订单,

最后结果按照第一列(source)升序排序

drop table if exists order_info;
drop table if exists client;
CREATE TABLE order_info (
id int(4) NOT NULL,
user_id int(11) NOT NULL,
product_name varchar(256) NOT NULL,
status varchar(32) NOT NULL,
client_id int(4) NOT NULL,
date date NOT NULL,
is_group_buy varchar(32) NOT NULL,
PRIMARY KEY (id)); CREATE TABLE client(
id int(4) NOT NULL,
name varchar(32) NOT NULL,
PRIMARY KEY (id)
); INSERT INTO order_info VALUES
(1,557336,'C++','no_completed',1,'2025-10-10','No'),
(2,230173543,'Python','completed',2,'2025-10-12','No'),
(3,57,'JS','completed',0,'2025-10-23','Yes'),
(4,57,'C++','completed',3,'2025-10-23','No'),
(5,557336,'Java','completed',0,'2025-10-23','Yes'),
(6,57,'Java','completed',1,'2025-10-24','No'),
(7,557336,'C++','completed',0,'2025-10-25','Yes'); INSERT INTO client VALUES
(1,'PC'),
(2,'Android'),
(3,'IOS'),
(4,'H5'); --
SELECT
IF(a.client_id = 0,'GroupBuy',c.name) AS source,
COUNT(*) AS cnt
FROM (
SELECT client_id
FROM order_info
WHERE
date > '2025-10-15'
AND STATUS = 'completed'
AND product_name IN ( 'C++', 'Java', 'Python' )
AND user_id IN (
SELECT user_id
FROM order_info
WHERE STATUS = 'completed'
GROUP BY user_id
HAVING COUNT( * ) >= 2
)
) AS a
LEFT JOIN client c ON a.client_id = c.id
GROUP BY a.client_id
ORDER BY source

  

最差是第几名(二)

查询一下,如果只有1个中位数,输出1个,如果有2个中位数,按grade升序输出

drop table if exists class_grade;
CREATE TABLE class_grade (
grade varchar(32) NOT NULL,
number int(4) NOT NULL
); INSERT INTO class_grade VALUES
('A',2),
('C',4),
('B',4),
('D',2); -- 题解
SELECT
grade
FROM
(
SELECT
grade,
( SELECT SUM(number) FROM class_grade c1 WHERE c1.grade < c2.grade ) AS s,
( SELECT SUM(number) FROM class_grade c1 WHERE c1.grade <= c2.grade ) AS e
FROM class_grade c2
ORDER BY grade
) AS t1,
(
SELECT sum( number ) AS sums
FROM class_grade
) AS t2
WHERE
( sums / 2 ) BETWEEN s AND e

  

获得积分最多的人

查找积分增加最高的用户的id(可能有多个),名字,以及他的总积分是多少,查询结果按照id升序排序

drop table if exists user;
drop table if exists grade_info; CREATE TABLE user (
id int(4) NOT NULL,
name varchar(32) NOT NULL
); CREATE TABLE grade_info (
user_id int(4) NOT NULL,
grade_num int(4) NOT NULL,
type varchar(32) NOT NULL
); INSERT INTO user VALUES
(1,'tm'),
(2,'wwy'),
(3,'zk'),
(4,'qq'),
(5,'lm'); INSERT INTO grade_info VALUES
(1,3,'add'),
(2,3,'add'),
(1,1,'add'),
(3,3,'add'),
(4,3,'add'),
(5,3,'add'),
(3,1,'add'); -- 1、获取所有人积分
SELECT `user_id`, SUM(`grade_num`) AS `total`
FROM
grade_info
WHERE `type` = 'add'
GROUP BY `user_id`
ORDER BY `total` DESC -- 2、获取积分最大值
SELECT SUM(`grade_num`) AS `grade_sum`
FROM grade_info
WHERE `type` = 'add'
GROUP BY user_id
ORDER BY `grade_sum` DESC LIMIT 1 -- 3、子查询筛选符合的用户
SELECT `user_id`, SUM(`grade_num`) AS `total`
FROM grade_info
WHERE `type` = 'add'
GROUP BY `user_id`
HAVING `total` = (
SELECT SUM(`grade_num`) AS `grade_sum`
FROM grade_info
WHERE `type` = 'add'
GROUP BY user_id
ORDER BY `grade_sum` DESC LIMIT 1
)
ORDER BY `total` DESC, `user_id` ASC -- 最终解题SQL
SELECT
`user`.`name`,
`main`.`total`
FROM
(
SELECT `user_id`, SUM(`grade_num`) AS `total`
FROM grade_info
WHERE `type` = 'add'
GROUP BY `user_id`
HAVING `total` = (
SELECT SUM(`grade_num`) AS `grade_sum`
FROM grade_info
WHERE `type` = 'add'
GROUP BY user_id
ORDER BY `grade_sum` DESC LIMIT 1
)
ORDER BY `total` DESC, `user_id` ASC
) AS `main`
JOIN `user` ON `main`.`user_id` = `user`.`id`

  

网易云音乐推荐(网易校招笔试真题)

查询向user_id = 1 的用户,推荐其关注的人喜欢的音乐。
不要推荐该用户已经喜欢的音乐,并且按music的id升序排列。你返回的结果中不应当包含重复项

CREATE TABLE `follow` (
`user_id` int(4) NOT NULL,
`follower_id` int(4) NOT NULL,
PRIMARY KEY (`user_id`,`follower_id`)); CREATE TABLE `music_likes` (
`user_id` int(4) NOT NULL,
`music_id` int(4) NOT NULL,
PRIMARY KEY (`user_id`,`music_id`)); CREATE TABLE `music` (
`id` int(4) NOT NULL,
`music_name` varchar(32) NOT NULL,
PRIMARY KEY (`id`)); INSERT INTO follow VALUES(1,2);
INSERT INTO follow VALUES(1,4);
INSERT INTO follow VALUES(2,3); INSERT INTO music_likes VALUES(1,17);
INSERT INTO music_likes VALUES(2,18);
INSERT INTO music_likes VALUES(2,19);
INSERT INTO music_likes VALUES(3,20);
INSERT INTO music_likes VALUES(4,17); INSERT INTO music VALUES(17,'yueyawang');
INSERT INTO music VALUES(18,'kong');
INSERT INTO music VALUES(19,'MOM');
INSERT INTO music VALUES(20,'Sold Out'); -- ID为1的用户的关注人
SELECT `follower_id`
FROM follow
WHERE `user_id` = 1 -- ID为1的用户 喜欢的音乐
SELECT music_id
FROM music_likes
WHERE `user_id` = 1 -- 关注的人喜欢的音乐
SELECT music_id
FROM music_likes
WHERE `user_id` IN (
SELECT `follower_id`
FROM follow
WHERE `user_id` = 1
) -- 去掉用户自己的音乐, 就是题目需要的歌曲了
SELECT music_id
FROM music_likes
WHERE
`user_id` IN (
SELECT `follower_id`
FROM follow
WHERE `user_id` = 1
)
AND music_id NOT IN (
SELECT music_id
FROM music_likes
WHERE `user_id` = 1
) -- 联表得出最终结果
SELECT music.`music_name`
FROM
(
SELECT music_id
FROM music_likes
WHERE
`user_id` IN (
SELECT `follower_id`
FROM follow
WHERE `user_id` = 1
)
AND music_id NOT IN (
SELECT music_id
FROM music_likes
WHERE `user_id` = 1
)
) AS `main`
JOIN `music` ON `main`.music_id = `music`.id
ORDER BY `music`.id ASC

  

【SQL】 牛客网SQL训练Part3 较难难度的更多相关文章

  1. MySql面试题、知识汇总、牛客网SQL专题练习

    点击名字直接跳转到链接: Linux运维必会的100道MySql面试题之(一) Linux运维必会的100道MySql面试题之(二) Linux运维必会的100道MySql面试题之(三) Linux运 ...

  2. 牛客网Sql

    牛客网Sql: 1.查询最晚入职的员工信息  select * from employees where hire_date =(select max(hire_date) from employee ...

  3. 牛客网sql刷题解析-完结

    查找最晚入职员工的所有信息 解题步骤: 题目:查询最晚入职员工的所有信息        目标:查询员工的所有信息 筛选条件:最晚入职           答案: SELECT *--查询所有信息就用* ...

  4. 牛客网sql练习

    一建表语句 /* Navicat MySQL Data Transfer Source Server : test Source Server Version : 50717 Source Host ...

  5. 牛客网sql实战参考答案(mysql版):16-21

    16.统计出当前(titles.to_date='9999-01-01')各个title类型对应的员工当前(salaries.to_date='9999-01-01')薪水对应的平均工资.结果给出ti ...

  6. 牛客网sql实战参考答案(mysql版):1-15

    1.查找最晚入职员工的所有信息,为了减轻入门难度,目前所有的数据里员工入职的日期都不是同一天(sqlite里面的注释为--,mysql为comment) CREATE TABLE `employees ...

  7. 牛客网数据库SQL实战解析(51-61题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  8. 牛客网数据库SQL实战解析(41-50题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  9. 牛客网数据库SQL实战解析(31-40题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

  10. 牛客网数据库SQL实战解析(21-30题)

    牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...

随机推荐

  1. Linux字符设备驱动学习

    注:本文是<Linux设备驱动开发详解:基于最新的Linux 4.0内核 by 宋宝华 >一书学习的笔记,大部分内容为书籍中的内容. 书籍可直接在微信读书中查看:Linux设备驱动开发详解 ...

  2. Lru在Rust中的实现, 源码解析

    LRU(Least Recently Used)是一种常用的页面置换算法,其核心思想是选择最近最久未使用的页面予以淘汰. LRU算法原理 基本思想:LRU算法基于一个假设,即如果一个数据在最近一段时间 ...

  3. jquery的class操作 css样式操作

        <button>切换</button>     <div class="div1">123</div>     <sc ...

  4. CF1016D

    problem & blog 构造题. 把从 \((1,1)\) 到 \((n - 1,m - 1)\) 的所有数变成 \(0\),这样从第 \(1\) 行到第 \(n - 1\) 行的最后一 ...

  5. sse 与 编译器自动优化

    direct x 形式的矩阵和向量计算代码在编译的时候是自动汇编为 sse汇编的 何时使用手写sse 指令呢,当你的应用程序需要写一些物理运算时候 可以使用自己编写的sse计算函数来为 3维运算加速 ...

  6. SRE 排障利器,接口请求超时试试 httpstat

    夜莺资深用户群有人推荐的一个工具,看了一下真挺好的,也推荐给大家. 需求场景 A 服务调用 B 服务的 HTTP 接口,发现 B 服务返回超时,不确定是网络的问题还是 B 服务的问题,需要排查. 工具 ...

  7. koishi机器docker搭建

    硬件要求: 可用内存:1G以上 存储空间:1G以上 cpu:不限制 配置: 在docker的存储空间目录建立koishi文件夹 下载docker镜像 koishijs/koishi 建立容器,具体设置 ...

  8. JS模拟循环批量请求后台接口

    使用async, await处理异步请求.用Promise, setTimeout函数模拟后台接口 <!DOCTYPE html> <html> <script type ...

  9. 牛客小白月赛96(待F)

    比赛链接:牛客小白月赛96 赛时感受 赛时在前面卡的时间有点长,C题没开longlong wa了n发,D题没考虑负数又wa了n发,然后来写E的时候时间就不长了,匆忙写一次交一发. A 思路 当其中一个 ...

  10. Spring Boot 整合 Fisco Bcos(部署、调用区块链合约)

    简介 在上一节,介绍了Spring Boot 整合 Fisco BCOS的最最基础的案例(SpringBoot成功连接Fisco BCOS,并访问其节点网络 --> 文章链接). 本节,咱们继续 ...