LeetCode
175. 组合两个表
Description
表1: Person
1 | +-------------+---------+ |
PersonId 是上表主键
表2: Address
1 | +-------------+---------+ |
AddressId 是上表主键
编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:
FirstName, LastName, City, State
Program
1 | # Write your MySQL query statement below |
178. 分数排名
Description
编写一个 SQL 查询来实现分数排名。
如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。
1 | +----+-------+ |
例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):
1 | +-------+------+ |
重要提示:对于 MySQL 解决方案,如果要转义用作列名的保留字,可以在关键字之前和之后使用撇号。例如 Rank
Program
1 | # Write your MySQL query statement below |
181. 超过经理收入的员工
Description
Employee 表包含所有员工,他们的经理也属于员工。每个员工都有一个 Id,此外还有一列对应员工的经理的 Id。
1 | +----+-------+--------+-----------+ |
给定 Employee 表,编写一个 SQL 查询,该查询可以获取收入超过他们经理的员工的姓名。在上面的表格中,Joe 是唯一一个收入超过他的经理的员工。
1 | +----------+ |
Program
内部联结
1 | # Write your MySQL query statement below |
182. 查找重复的电子邮箱
Description
编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。
示例:
1 | +----+---------+ |
根据以上输入,你的查询应返回以下结果:
1 | +---------+ |
说明:所有电子邮箱都是小写字母。
Program
分组过滤
1 | # Write your MySQL query statement below |
183. 从不订购的客户
Description
某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。
Customers 表:
1 | +----+-------+ |
Orders 表:
1 | +----+------------+ |
例如给定上述表格,你的查询应返回:
1 | +-----------+ |
Program
①嵌套查询
1 | # Write your MySQL query statement below |
②外联结
1 | # Write your MySQL query statement below |
196. 删除重复的电子邮箱
Description
编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。
1 | +----+------------------+ |
Id 是这个表的主键。
例如,在运行你的查询语句之后,上面的 Person 表应返回以下几行:
1 | +----+------------------+ |
提示:
执行 SQL 之后,输出是整个 Person 表。
使用 delete 语句。
Program
思路
使用自联结
1 | # Write your MySQL query statement below |
197. 上升的温度
Description
表 Weather
1 | +---------------+---------+ |
id 是这个表的主键
该表包含特定日期的温度信息
编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 id 。
返回结果 不要求顺序 。
查询结果格式如下例:
Weather
1 | +----+------------+-------------+ |
Result table:
1 | +----+ |
2015-01-02 的温度比前一天高(10 -> 25)
2015-01-04 的温度比前一天高(30 -> 20)
Program
联结+函数
联结后日期比较函数DATEDIFF(date1, date2)返回date1 - date2的日期差。
1 | # Write your MySQL query statement below |
595. 大的国家
Description
这里有张 World 表
1 | +-----------------+------------+------------+--------------+---------------+ |
如果一个国家的面积超过 300 万平方公里,或者人口超过 2500 万,那么这个国家就是大国家。
编写一个 SQL 查询,输出表中所有大国家的名称、人口和面积。
例如,根据上表,我们应该输出:
1 | +--------------+-------------+--------------+ |
Program
1 | # Write your MySQL query statement below |
596. 超过5名学生的课
Description
有一个courses 表 ,有: student (学生) 和 class (课程)。
请列出所有超过或等于5名学生的课。
例如,表:
1 | +---------+------------+ |
应该输出:
1 | +---------+ |
提示:
学生在每个课中不应被重复计算。
Program
1 | # Write your MySQL query statement below |
620. 有趣的电影
Description
某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 LED显示板做电影推荐,上面公布着影评和相关电影描述。
作为该电影院的信息部主管,您需要编写一个 SQL查询,找出所有影片描述为非 boring (不无聊) 的并且 id 为奇数 的影片,结果请按等级 rating 排列。
例如,下表 cinema:
1 | +---------+-----------+--------------+-----------+ |
对于上面的例子,则正确的输出是为:
1 | +---------+-----------+--------------+-----------+ |
Program
1 | # Write your MySQL query statement below |
627. 变更性别
Description
给定一个 salary 表,如下所示,有 m = 男性 和 f = 女性 的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求只使用一个更新(Update)语句,并且没有中间的临时表。
注意,您必只能写一个 Update 语句,请不要编写任何 Select 语句。
例如:
1 | | id | name | sex | salary | |
运行你所编写的更新语句之后,将会得到以下表:
1 | | id | name | sex | salary | |
Program
表达式
1 | # Write your MySQL query statement below |
1179. 重新格式化部门表
Description
部门表 Department:
1 | +---------------+---------+ |
(id, month) 是表的联合主键。
这个表格有关于每个部门每月收入的信息。
月份(month)可以取下列值 [“Jan”,”Feb”,”Mar”,”Apr”,”May”,”Jun”,”Jul”,”Aug”,”Sep”,”Oct”,”Nov”,”Dec”]。
编写一个 SQL 查询来重新格式化表,使得新的表中有一个部门 id 列和一些对应 每个月 的收入(revenue)列。
查询结果格式如下面的示例所示:
Department 表:
1 | +------+---------+-------+ |
查询得到的结果表:
1 | +------+-------------+-------------+-------------+-----+-------------+ |
注意,结果表有 13 列 (1个部门 id 列 + 12个月份的收入列)。
Program
1 | # Write your MySQL query statement below |
牛客
SQL01 查找最晚入职员工的所有信息
题目描述
查找最晚入职员工的所有信息,为了减轻入门难度,目前所有的数据里员工入职的日期都不是同一天(sqlite里面的注释为–,mysql为comment)
1 | CREATE TABLE `employees` ( |
输出描述
|emp_no|birth_date|first_name|last_name|gender|hire_date|
|–|–|–|–|–|–|–|
|10008|1958-02-19|Saniya|Kalloufi|M|1994-09-15|
程序
1 | SELECT * |
SQL02 查找入职员工时间排名倒数第三的员工所有信息
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
));
1 | **输出描述** |
SQL03 查找各个部门当前领导当前薪水详情以及其对应部门编号dept_no
题目描述
查找各个部门当前(dept_manager.to_date=’9999-01-01’)领导当前(salaries.to_date=’9999-01-01’)薪水详情以及其对应部门编号dept_no
(注:输出结果以salaries.emp_no升序排序,并且请注意输出结果里面dept_no列是最后一列)
1 | CREATE TABLE `salaries` ( |
思路
题目要求从两个表中
1 | SELECT s.emp_no, s.salary, s.from_date, s.to_date, d.dept_no |
SQL04 查找所有已经分配部门的员工的last_name和first_name
题目描述
查找所有已经分配部门的员工的last_name和first_name以及dept_no(请注意输出描述里各个列的前后顺序)
1 | CREATE TABLE `dept_emp` ( |
程序
1 | SELECT e.last_name, e.first_name, d.dept_no |
SQL05 查找所有员工的last_name和first_name以及对应部门编号dept_no
题目描述
查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括暂时没有分配具体部门的员工(请注意输出描述里各个列的前后顺序)
1 | CREATE TABLE `dept_emp` ( |
程序
1 | SELECT e.last_name, e.first_name, d.dept_no |
SQL06 查找所有员工入职时候的薪水情况
题目描述
查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序(请注意,一个员工可能有多次涨薪的情况)
1 | CREATE TABLE `employees` ( |
程序
1 | SELECT e.emp_no, s.salary |
SQL07 查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t
题目描述
查找薪水变动超过15次的员工号emp_no以及其对应的变动次数t
1 | CREATE TABLE `salaries` ( |
程序
1 | SELECT emp_no, COUNT(emp_no) as t |
SQL08 找出所有员工当前具体的薪水salary情况
题目描述
找出所有员工当前(to_date=’9999-01-01’)具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
1 | CREATE TABLE `salaries` ( |
程序
1 | SELECT DISTINCT salary |
SQL09 获取所有部门当前manager的当前薪水情况
题目描述
获取所有部门当前(dept_manager.to_date=’9999-01-01’)manager的当前(salaries.to_date=’9999-01-01’)薪水情况,给出dept_no, emp_no以及salary,输出结果按照dept_no升序排列(请注意,同一个人可能有多条薪水情况记录)
1 | CREATE TABLE `dept_manager` ( |
程序
1 | SELECT d.dept_no, s.emp_no, s.salary |
SQL10 获取所有非manager的员工emp_no
题目描述
获取所有非manager的员工emp_no
1 | CREATE TABLE `dept_manager` ( |
程序
1 | SELECT e.emp_no |
SQL11 获取所有员工当前的manager
题目描述
获取所有员工当前的(dept_manager.to_date=’9999-01-01’)manager,如果员工是manager的话不显示(也就是如果当前的manager是自己的话结果不显示)。输出结果第一列给出当前员工的emp_no,第二列给出其manager对应的emp_no。
1 | CREATE TABLE `dept_emp` ( |
程序
1 | SELECT de.emp_no as emp_no, dm.emp_no as manager_no |
SQL12 获取所有部门中当前员工薪水最高的相关信息
题目描述
获取所有部门中当前(dept_emp.to_date = ‘9999-01-01’)员工当前(salaries.to_date=’9999-01-01’)薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary,按照部门编号升序排列。
1 | CREATE TABLE `dept_emp` ( |
程序
子查询查找每个部门中满足条件的最高薪水,然后外表根据最高薪水进行选择。
1 | SELECT d.dept_no, s.emp_no, s.salary |
SQL13 从titles表获取按照title进行分组
题目描述
从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
1 | CREATE TABLE IF NOT EXISTS "titles" ( |
程序
1 | SELECT title, COUNT(*) |
SQL14 从titles表获取按照title进行分组,注意对于重复的emp_no进行忽略。
题目描述
从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
注意对于重复的emp_no进行忽略(即emp_no重复的title不计算,title对应的数目t不增加)。
1 | CREATE TABLE IF NOT EXISTS `titles` ( |
程序
分组后去重emp_no
1 | SELECT title, COUNT(DISTINCT(emp_no)) |
SQL15 查找employees表所有emp_no为奇数
题目描述
查找employees表所有emp_no为奇数,且last_name不为Mary(注意大小写)的员工信息,并按照hire_date逆序排列
复制代码
1 | CREATE TABLE `employees` ( |
程序
1 | SELECT * |
SQL16 统计出当前各个title类型对应的员工当前薪水对应的平均工资
题目描述
统计出当前(titles.to_date=’9999-01-01’)各个title类型对应的员工当前(salaries.to_date=’9999-01-01’)薪水对应的平均工资。结果给出title以及平均工资avg。
1 | CREATE TABLE `salaries` ( |
程序
1 | SELECT t.title, AVG(s.salary) |
SQL17 获取当前薪水第二多的员工的emp_no以及其对应的薪水salary
题目描述
获取当前(to_date=’9999-01-01’)薪水第二多的员工的emp_no以及其对应的薪水salary
1 | CREATE TABLE `salaries` ( |
程序
1 | SELECT emp_no, salary |
SQL18 查找当前薪水排名第二多的员工编号emp_no
题目描述
查找当前薪水(to_date=’9999-01-01’)排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,你可以不使用order by完成吗
1 | CREATE TABLE `employees` ( |
程序
1 | SELECT s.emp_no, s.salary, e.last_name, e.first_name |
1 | SELECT s.emp_no, s.salary, e.last_name, e.first_name |
SQL19 查找所有员工的last_name和first_name以及对应的dept_name
题目描述
查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
1 | CREATE TABLE `departments` ( |
程序
1 | SELECT e.last_name, e.first_name, |
1 | SELECT e.last_name, e.first_name, dp.dept_name |
SQL20 查找员工编号emp_now为10001其自入职以来的薪水salary涨幅值growth
题目描述
查找员工编号emp_no为10001其自入职以来的薪水salary涨幅(总共涨了多少)growth(可能有多次涨薪,没有降薪)
1 | CREATE TABLE `salaries` ( |
程序
1 | SELECT MAX(salary) - MIN(salary) AS growth |
SQL21 查找所有员工自入职以来的薪水涨幅情况
题目描述
查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序
(注:可能有employees表和salaries表里存在记录的员工,有对应的员工编号和涨薪记录,但是已经离职了,离职的员工salaries表的最新的to_date!=’9999-01-01’,这样的数据不显示在查找结果里面)
1 | CREATE TABLE `employees` ( |
程序
1 | SELECT s1.emp_no, s1.salary - s2.salary AS growth |
SQL22 统计各个部门的工资记录数
题目描述
统计各个部门的工资记录数,给出部门编码dept_no、部门名称dept_name以及部门在salaries表里面有多少条记录sum,按照dept_no升序排序
1 | CREATE TABLE `departments` ( |
程序
1 | SELECT dp.dept_no, dp.dept_name, COUNT(*) AS sum |
SQL23 对所有员工的当前薪水按照salary进行按照1-N的排名
题目描述
对所有员工的当前(to_date=’9999-01-01’)薪水按照salary进行按照1-N的排名,相同salary并列且按照emp_no升序排列
1 | CREATE TABLE `salaries` ( |
程序
下面介绍三种用于进行排序的专用窗口函数:
1、RANK()
在计算排序时,若存在相同位次,会跳过之后的位次。
例如,有3条排在第1位时,排序为:1,1,1,4······
2、DENSE_RANK()
这就是题目中所用到的函数,在计算排序时,若存在相同位次,不会跳过之后的位次。
例如,有3条排在第1位时,排序为:1,1,1,2······
3、ROW_NUMBER()
这个函数赋予唯一的连续位次。
例如,有3条排在第1位时,排序为:1,2,3,4······
窗口函数用法:
<窗口函数> OVER ( [PARTITION BY <列清单> ]
ORDER BY <排序用列清单> )
*其中[ ]中的内容可以忽略
1 | SELECT emp_no, salary, |
SQL24 获取所有非manager员工当前的薪水情况
题目描述
获取所有非manager员工当前的薪水情况,给出dept_no、emp_no以及salary ,当前表示to_date=’9999-01-01’
1 | CREATE TABLE `dept_emp` ( |
程序
1 | SELECT de.dept_no, e.emp_no, s.salary |
SQL25 获取员工其当前的薪水比其manager当前薪水还高的相关信息
题目描述
获取员工其当前的薪水比其manager当前薪水还高的相关信息,当前表示to_date=’9999-01-01’,
结果第一列给出员工的emp_no,
第二列给出其manager的manager_no,
第三列给出该员工当前的薪水emp_salary,
第四列给该员工对应的manager当前的薪水manager_salary
1 | CREATE TABLE `dept_emp` ( |
程序
(1)先让员工表与工资表按照员工编号emp_no内连接,得到员工的工资;
(2)再根据dept_no连接管理员表;
(3)再根据管理员表的emp_no与工资表连接,得到管理员的工资;
1 | SELECT de.emp_no, dm.emp_no AS manager_no, s1.salary AS emp_salary, s2.salary AS manager_salary |
SQL26 汇总各个部门当前员工的title类型的分配数目
题目描述
汇总各个部门当前员工的title类型的分配数目,即结果给出部门编号dept_no、dept_name、其部门下所有的当前(dept_emp.to_date = ‘9999-01-01’)员工的当前(titles.to_date = ‘9999-01-01’)title以及该类型title对应的数目count,结果按照dept_no升序排序
(注:因为员工可能有离职,所有dept_emp里面to_date不为’9999-01-01’就已经离职了,不计入统计,而且员工可能有晋升,所以如果titles.to_date 不为 ‘9999-01-01’,那么这个可能是员工之前的职位信息,也不计入统计)
1 | CREATE TABLE `departments` ( |
程序
(1)先按照dept_no联结departments和dept_emp;
(2)再按照emp_no联结titles;
(3)题目需要按dept_no排序,所以最后需要ORDER BY dept_no;
(4)最关键的在于需要统计每个部门内的每个title类型的数量,所以需要先对dept_no部门进行分组,而后再对每个部门内的title类型进行分组,最后统计COUNT(title)计算的就是所求;
关键点GROUP BY dp.dept_no, t.title
1 | SELECT dp.dept_no, dp.dept_name, t.title, COUNT(t.title) AS 'count' |
SQL28 查找描述信息中包括robot的电影对应的分类名称以及电影数目
题目描述
查找描述信息(film.description)中包含robot的电影对应的分类名称(category.name)以及电影数目(count(film.film_id)),而且还需要该分类包含电影总数量(count(film_category.category_id))>=5部
1 | CREATE TABLE IF NOT EXISTS film ( |
程序
(1)注意,分类下电影总数不是包含robot的而是原始film_category下计算的电影总数大于等于5;
(2)其他按规则联结。
1 | SELECT c.name as '分类名称actegory.name', |
SQL29 使用join查询方式找出没有分类的电影id以及名称
题目描述
使用join查询方式找出没有分类的电影id以及名称
1 | CREATE TABLE IF NOT EXISTS film ( |
程序
1 | SELECT f.film_id, f.title |
SQL30 使用子查询的方式找出属于Action分类的所有电影对应的title,description
题目描述
你能使用子查询的方式找出属于Action分类的所有电影对应的title,description吗
1 | CREATE TABLE IF NOT EXISTS film ( |
程序
1 | SELECT f.title, f.description |
SQL32 将employees表的所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分
题目描述
将employees表的所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分
(注:sqllite,字符串拼接为 || 符号,不支持concat函数,mysql支持concat函数)
1 | CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, |
程序
1 | SELECT CONCAT(e.last_name, ' ', e.first_name) as Name # CONCATE(str1, str2, ...) |
1 | SELECT CONCAT_WS(' ', e.last_name, e.first_name) as Name # CONCATE_WS(seperator, str1, str2, ...) |
SQL33 创建一个actor表,包含如下列信息
题目描述
创建一个actor表,包含如下列信息
|列表| 类型| 是否为NULL| 含义|
|–|–|–|–|
|actor_id| smallint(5) |not null |主键id|
|first_name |varchar(45) |not null |名字|
|last_name| varchar(45) |not null| 姓氏|
|last_update| date |not null| 日期|
程序
1 | CREATE TABLE actor( |
SQL34 批量插入数据
题目描述
题目已经先执行了如下语句:
1 | drop table if exists actor; |
请你对于表actor批量插入如下数据(不能有2条insert语句哦!)
|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|
程序
1 | INSERT INTO actor(actor_id,first_name,last_name,last_update) |
SQL35 批量插入数据,如果数据已经存在,请忽略,不使用replace操作
题目描述
题目已经先执行了如下语句:
1 | drop table if exists actor; |
对于表actor插入如下数据,如果数据已经存在,请忽略(不支持使用replace操作)
1 | '3' 'ED' 'CHASE' '2006-02-15 12:34:33' |
程序
1 | INSERT IGNORE INTO actor(actor_id, |
SQL36 创建一个actor_name表,将actor表中的所有first_name以及last_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 姓氏
程序
1 | CREATE TABLE IF NOT EXISTS actor_name( |
SQL37 对first_name创建唯一索引uniq_idx_firstname,对last_name创建普通索引idx_lastname
题目描述
针对如下表actor结构创建索引:
(注:在 SQLite 中,除了重命名表和在已有的表中添加列,ALTER TABLE 命令不支持其他操作,
mysql支持ALTER TABLE创建索引)
1 | CREATE TABLE actor ( |
程序
1 | ALTER TABLE actor ADD UNIQUE uniq_idx_firstname(first_name); |