我是靠谱客的博主 飞快店员,最近开发中收集的这篇文章主要介绍Leetcode|MySQL|数据库刷题记录(601~627)601. 体育馆的人流量602. 好友申请 II :谁有最多的好友603. 连续空余座位 607. 销售员 608. 树节点 610. 判断三角形 612. 平面上的最近距离 613. 直线上的最近距离 614. 二级关注者615. 平均工资:部门与公司比较 618. 学生地理信息报告 619. 只出现一次的最大数字 620. 有趣的电影 626. 换座位 627. 变更性别,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

601. 体育馆的人流量

602. 好友申请 II :谁有最多的好友

603. 连续空余座位

 607. 销售员

 608. 树节点

 610. 判断三角形

 612. 平面上的最近距离

 613. 直线上的最近距离

 614. 二级关注者

615. 平均工资:部门与公司比较

 618. 学生地理信息报告

 619. 只出现一次的最大数字

 620. 有趣的电影

 626. 换座位

 627. 变更性别


601. 体育馆的人流量

https://leetcode-cn.com/problems/human-traffic-of-stadium/

表:Stadium
+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| visit_date    | date    |
| people        | int     |
+---------------+---------+
visit_date 是表的主键
每日人流量信息被记录在这三列信息中:序号 (id)、日期 (visit_date)、 人流量 (people)
每天只有一行记录,日期随着 id 的增加而增加
 

编写一个 SQL 查询以找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录。

返回按 visit_date 升序排列的结果表。

查询结果格式如下所示。

Stadium table:
+------+------------+-----------+
| id   | visit_date | people    |
+------+------------+-----------+
| 1    | 2017-01-01 | 10        |
| 2    | 2017-01-02 | 109       |
| 3    | 2017-01-03 | 150       |
| 4    | 2017-01-04 | 99        |
| 5    | 2017-01-05 | 145       |
| 6    | 2017-01-06 | 1455      |
| 7    | 2017-01-07 | 199       |
| 8    | 2017-01-09 | 188       |
+------+------------+-----------+

Result table:
+------+------------+-----------+
| id   | visit_date | people    |
+------+------------+-----------+
| 5    | 2017-01-05 | 145       |
| 6    | 2017-01-06 | 1455      |
| 7    | 2017-01-07 | 199       |
| 8    | 2017-01-09 | 188       |
+------+------------+-----------+
id 为 5、6、7、8 的四行 id 连续,并且每行都有 >= 100 的人数记录。
请注意,即使第 7 行和第 8 行的 visit_date 不是连续的,输出也应当包含第 8 行,因为我们只需要考虑 id 连续的记录。
不输出 id 为 2 和 3 的行,因为至少需要三条 id 连续的记录。

思路:这道题是比较难一点。。。难点在于怎么找出连续的三行或以上记录 ,最后还是参考了题解里面的方法,个人觉得最好理解是下面这种做法

基本思路就是因为我们要找出连续的三行记录,可以很自然地想到用LAG或LEAD函数获取当前行的前一行/前两行/后一行/后两行的people值,一开始我只想到用LEAD获取后一行和后两行的值,然后判断这三行连续记录的people值是否都大于等于100,但是这样的话有一个问题,就是当前行的id始终是三个里面最小的id,最后始终取不到连续的id中的最大的那个id。

后来看到题解才知道原来可以同时用LAG和LEAD,这样在一行记录里面,既有当前行的前几行的people值也有后几行的people值,在判断的时候可以把当前行id当成是最小、中间、最大来判断,这样就省事很多了。

SELECT t.id, t.visit_date, t.people
FROM
(
SELECT *,
LAG(people, 2) OVER(ORDER BY id) AS pre2,
LAG(people, 1) OVER(ORDER BY id) AS pre1,
LEAD(people, 1) OVER(ORDER BY id) AS post1,
LEAD(people, 2) OVER(ORDER BY id) AS post2
FROM Stadium
) t
WHERE t.people>=100
AND
(
(t.pre2>=100 AND t.pre1>=100)
OR (t.pre1>=100 AND t.post1>=100)
OR (t.post1>=100 AND t.post2>=100)
)

602. 好友申请 II :谁有最多的好友

https://leetcode-cn.com/problems/friend-requests-ii-who-has-the-most-friends/

在 Facebook 或者 Twitter 这样的社交应用中,人们经常会发好友申请也会收到其他人的好友申请。

 

表 request_accepted 存储了所有好友申请通过的数据记录,其中, requester_id 和 accepter_id 都是用户的编号。

 

| requester_id | accepter_id | accept_date|
|--------------|-------------|------------|
| 1            | 2           | 2016_06-03 |
| 1            | 3           | 2016-06-08 |
| 2            | 3           | 2016-06-08 |
| 3            | 4           | 2016-06-09 |
写一个查询语句,求出谁拥有最多的好友和他拥有的好友数目。对于上面的样例数据,结果为:

| id | num |
|----|-----|
| 3  | 3   |
注意:

保证拥有最多好友数目的只有 1 个人。
好友申请只会被接受一次,所以不会有 requester_id 和 accepter_id 值都相同的重复记录。
 

解释:

编号为 '3' 的人是编号为 '1','2' 和 '4' 的好友,所以他总共有 3 个好友,比其他人都多。

 

进阶:

在真实世界里,可能会有多个人拥有好友数相同且最多,你能找到所有这些人吗?

 思路:我们只需要将requester_id和accepter_id合并成一列,再统计每个id出现的次数,再排序就可以了。

使用UNION ALL将requester_id和accepter_id合并成一列,注意不是UNION,因为UNION会把重复值删掉,UNION ALL会保留重复值;然后使用GROUP BY和ORDER BY对每个id出现的次数进行统计和排序,用LIMIT 1取出次数最多的id即可

SELECT t.id, COUNT(*) AS num
FROM
(
SELECT requester_id AS id FROM request_accepted
UNION ALL
SELECT accepter_id FROM request_accepted
) t
GROUP BY t.id
ORDER BY COUNT(*) DESC
LIMIT 1

603. 连续空余座位

https://leetcode-cn.com/problems/consecutive-available-seats/

几个朋友来到电影院的售票处,准备预约连续空余座位。

你能利用表 cinema ,帮他们写一个查询语句,获取所有空余座位,并将它们按照 seat_id 排序后返回吗?

| seat_id | free |
|---------|------|
| 1       | 1    |
| 2       | 0    |
| 3       | 1    |
| 4       | 1    |
| 5       | 1    |
 

对于如上样例,你的查询语句应该返回如下结果。

 

| seat_id |
|---------|
| 3       |
| 4       |
| 5       |
注意:

seat_id 字段是一个自增的整数,free 字段是布尔类型('1' 表示空余, '0' 表示已被占据)。
连续空余座位的定义是大于等于 2 个连续空余的座位。

思路:这道题的做法和第601题是一样的,用LAG(free, 1)和LEAD(free, 1)获取当前行的前一行和后一行的free值,只要当前行free=1且满足下面其中一个条件,当前行free=1且前一行free=1,或者当前行free=1且后一行free=1,即可 。最后记得要对得到的seat_id排序。

SELECT t.seat_id
FROM
(
SELECT seat_id, free,
LAG(free, 1) OVER(ORDER BY seat_id) AS pre1,
LEAD(free, 1) OVER(ORDER BY seat_id) AS post1
FROM cinema
) t
WHERE t.free=1
AND ((t.free=1 AND t.pre1=1) OR (t.free=1 AND t.post1))
ORDER BY t.seat_id

 607. 销售员

https://leetcode-cn.com/problems/sales-person/

描述

给定 3 个表: salesperson, company, orders。
输出所有表 salesperson 中,没有向公司 'RED' 销售任何东西的销售员。

示例:
输入

表: salesperson

+----------+------+--------+-----------------+-----------+
| sales_id | name | salary | commission_rate | hire_date |
+----------+------+--------+-----------------+-----------+
|   1      | John | 100000 |     6           | 4/1/2006  |
|   2      | Amy  | 120000 |     5           | 5/1/2010  |
|   3      | Mark | 65000  |     12          | 12/25/2008|
|   4      | Pam  | 25000  |     25          | 1/1/2005  |
|   5      | Alex | 50000  |     10          | 2/3/2007  |
+----------+------+--------+-----------------+-----------+
表 salesperson 存储了所有销售员的信息。每个销售员都有一个销售员编号 sales_id 和他的名字 name 。

表: company

+---------+--------+------------+
| com_id  |  name  |    city    |
+---------+--------+------------+
|   1     |  RED   |   Boston   |
|   2     | ORANGE |   New York |
|   3     | YELLOW |   Boston   |
|   4     | GREEN  |   Austin   |
+---------+--------+------------+
表 company 存储了所有公司的信息。每个公司都有一个公司编号 com_id 和它的名字 name 。

表: orders

+----------+------------+---------+----------+--------+
| order_id | order_date | com_id  | sales_id | amount |
+----------+------------+---------+----------+--------+
| 1        |   1/1/2014 |    3    |    4     | 100000 |
| 2        |   2/1/2014 |    4    |    5     | 5000   |
| 3        |   3/1/2014 |    1    |    1     | 50000  |
| 4        |   4/1/2014 |    1    |    4     | 25000  |
+----------+----------+---------+----------+--------+
表 orders 存储了所有的销售数据,包括销售员编号 sales_id 和公司编号 com_id 。

输出

+------+
| name | 
+------+
| Amy  | 
| Mark | 
| Alex |
+------+
解释

根据表 orders 中的订单 '3' 和 '4' ,容易看出只有 'John' 和 'Pam' 两个销售员曾经向公司 'RED' 销售过。

所以我们需要输出表 salesperson 中所有其他人的名字。s 

思路:这道题也比较简单,但是我一开始为了图方便没有用到company表,而是直接在orders表里面找com_id=1的记录,结果没通过,后来老老实实把company表和orders表连接起来,用name='RED'来筛选记录,然后从salesperson表中没有向RED公司销售过的人员id。 

SELECT name
FROM salesperson
WHERE sales_id NOT IN
(
SELECT sales_id
FROM orders a LEFT JOIN company b ON a.com_id=b.com_id
WHERE b.name='RED'
) 

 608. 树节点

https://leetcode-cn.com/problems/tree-node/

给定一个表 tree,id 是树节点的编号, p_id 是它父节点的 id 。

+----+------+
| id | p_id |
+----+------+
| 1  | null |
| 2  | 1    |
| 3  | 1    |
| 4  | 2    |
| 5  | 2    |
+----+------+
树中每个节点属于以下三种类型之一:

叶子:如果这个节点没有任何孩子节点。
根:如果这个节点是整棵树的根,即没有父节点。
内部节点:如果这个节点既不是叶子节点也不是根节点。
 

写一个查询语句,输出所有节点的编号和节点的类型,并将结果按照节点编号排序。上面样例的结果为:

 

+----+------+
| id | Type |
+----+------+
| 1  | Root |
| 2  | Inner|
| 3  | Leaf |
| 4  | Leaf |
| 5  | Leaf |
+----+------+
 

解释

节点 '1' 是根节点,因为它的父节点是 NULL ,同时它有孩子节点 '2' 和 '3' 。
节点 '2' 是内部节点,因为它有父节点 '1' ,也有孩子节点 '4' 和 '5' 。
节点 '3', '4' 和 '5' 都是叶子节点,因为它们都有父节点同时没有孩子节点。
样例中树的形态如下:
 

              1
            /  
                      2       3
                    /  
                  4       5
 

注意

如果树中只有一个节点,你只需要输出它的根属性。

 思路:通过观察,如果p_id为null的话,该节点即为根节点;如果p_id不为null且id在p_id列出现过,就说明该节点是别的节点的父节点且不是根节点,也就是是中间结点;如果p_id不为null且id没有在p_id列出现过的话,说明该节点不是别的节点的父节点且不是根节点,也就是叶子结点。

用CASE WHEN 语句列出上述3种情况来判断即可。

SELECT id,
CASE WHEN p_id is null THEN 'Root'
WHEN p_id is not null AND id IN (SELECT p_id FROM tree) THEN 'Inner'
ELSE 'Leaf'
END AS Type
FROM tree 

 610. 判断三角形

https://leetcode-cn.com/problems/triangle-judgement/

一个小学生 Tim 的作业是判断三条线段是否能形成一个三角形。

然而,这个作业非常繁重,因为有几百组线段需要判断。

假设表 triangle 保存了所有三条线段的长度 x、y、z ,请你帮 Tim 写一个查询语句,来判断每组 x、y、z 是否可以组成一个三角形?

 

| x  | y  | z  |
|----|----|----|
| 13 | 15 | 30 |
| 10 | 20 | 15 |
对于如上样例数据,你的查询语句应该返回如下结果:

| x  | y  | z  | triangle |
|----|----|----|----------|
| 13 | 15 | 30 | No       |
| 10 | 20 | 15 | Yes      |

思路:三条边形成三角形的条件是任意两条边加起来大于另一条边 

SELECT *,
IF(x+y>z AND x+z>y AND y+z>x, 'Yes', 'No') AS triangle
FROM triangle

 612. 平面上的最近距离

https://leetcode-cn.com/problems/shortest-distance-in-a-plane/ 

表 point_2d 保存了所有点(多于 2 个点)的坐标 (x,y) ,这些点在平面上两两不重合。

 

写一个查询语句找到两点之间的最近距离,保留 2 位小数。

 

| x  | y  |
|----|----|
| -1 | -1 |
| 0  | 0  |
| -1 | -2 |
 

最近距离在点 (-1,-1) 和(-1,2) 之间,距离为 1.00 。所以输出应该为:

 

| shortest |
|----------|
| 1.00     |
 

注意:任意点之间的最远距离小于 10000 。

思路:平面两点间最近距离即欧氏距离。将原表进行自连接,两两计算欧氏距离,取距离最短的。 

SELECT MIN(ROUND(SQRT(POWER(a.x-b.x, 2)+POWER(a.y-b.y,2)), 2)) AS shortest
FROM point_2d a JOIN point_2d b
ON a.x!=b.x OR a.y!=b.y

 613. 直线上的最近距离

https://leetcode-cn.com/problems/shortest-distance-in-a-line/

表 point 保存了一些点在 x 轴上的坐标,这些坐标都是整数。

 

写一个查询语句,找到这些点中最近两个点之间的距离。

 

| x   |
|-----|
| -1  |
| 0   |
| 2   |
 

最近距离显然是 '1' ,是点 '-1' 和 '0' 之间的距离。所以输出应该如下:

 

| shortest|
|---------|
| 1       |
 

注意:每个点都与其他点坐标不同,表 table 不会有重复坐标出现。

 

进阶:如果这些点在 x 轴上从左到右都有一个编号,输出结果时需要输出最近点对的编号呢?

思路:和上面那道题的思路是一样的,这题更简单一点,首先自连接表,然后直接求两个点的x坐标的差的绝对值,取最小值就行了。 

SELECT MIN(ABS(a.x-b.x)) AS shortest
FROM point a JOIN point b
ON a.x!=b.x 

 614. 二级关注者

https://leetcode-cn.com/problems/second-degree-follower/

在 facebook 中,表 follow 会有 2 个字段: followee, follower ,分别表示被关注者和关注者。

请写一个 sql 查询语句,对每一个关注者,查询关注他的关注者的数目。

比方说:

+-------------+------------+
| followee    | follower   |
+-------------+------------+
|     A       |     B      |
|     B       |     C      |
|     B       |     D      |
|     D       |     E      |
+-------------+------------+
应该输出:

+-------------+------------+
| follower    | num        |
+-------------+------------+
|     B       |  2         |
|     D       |  1         |
+-------------+------------+
解释:

B 和 D 都在在 follower 字段中出现,作为被关注者,B 被 C 和 D 关注,D 被 E 关注。A 不在 follower 字段内,所以A不在输出列表中。

 

注意:

被关注者永远不会被他 / 她自己关注。
将结果按照字典序返回。

 思路:对出现在follower里面的followee的关注者进行统计,然后按照followee的字典序进行排序。

ps:COUNT的时候一定要记得去重!!

SELECT followee AS follower, COUNT(DISTINCT follower) AS num
FROM follow
WHERE followee IN (SELECT follower FROM follow)
GROUP BY followee
ORDER BY followee

615. 平均工资:部门与公司比较

https://leetcode-cn.com/problems/average-salary-departments-vs-company/

给如下两个表,写一个查询语句,求出在每一个工资发放日,每个部门的平均工资与公司的平均工资的比较结果 (高 / 低 / 相同)。

 

表: salary

| id | employee_id | amount | pay_date   |
|----|-------------|--------|------------|
| 1  | 1           | 9000   | 2017-03-31 |
| 2  | 2           | 6000   | 2017-03-31 |
| 3  | 3           | 10000  | 2017-03-31 |
| 4  | 1           | 7000   | 2017-02-28 |
| 5  | 2           | 6000   | 2017-02-28 |
| 6  | 3           | 8000   | 2017-02-28 |
 

employee_id 字段是表 employee 中 employee_id 字段的外键。

 

| employee_id | department_id |
|-------------|---------------|
| 1           | 1             |
| 2           | 2             |
| 3           | 2             |
 

对于如上样例数据,结果为:

 

| pay_month | department_id | comparison  |
|-----------|---------------|-------------|
| 2017-03   | 1             | higher      |
| 2017-03   | 2             | lower       |
| 2017-02   | 1             | same        |
| 2017-02   | 2             | same        |
 

解释

 

在三月,公司的平均工资是 (9000+6000+10000)/3 = 8333.33...

 

由于部门 '1' 里只有一个 employee_id 为 '1' 的员工,所以部门 '1' 的平均工资就是此人的工资 9000 。因为 9000 > 8333.33 ,所以比较结果是 'higher'。

 

第二个部门的平均工资为 employee_id 为 '2' 和 '3' 两个人的平均工资,为 (6000+10000)/2=8000 。因为 8000 < 8333.33 ,所以比较结果是 'lower' 。

 

在二月用同样的公式求平均工资并比较,比较结果为 'same' ,因为部门 '1' 和部门 '2' 的平均工资与公司的平均工资相同,都是 7000 。

思路:用窗口函数AVG(amount)分别在两个窗口计算平均工资,一个是月内各部门的平均工资,一个是月内所有部门平均工资,所以区别就是前者的窗口在PARTITION BY pay_month的基础上还要再根据department_id进行分组。用完窗口函数后由于组内每条记录都跟着接了相同的两个平均工资,而我们只需要一条记录,所以要使用DISTINCT获取唯一的department_id和pay_mouth 以及他们对应的两个平均工资。然后在外层比较月内各部门平均工资和月内所有部门平均工资的大小,用CASE WHEN来判断comparison字段的赋值为higher,same还是lower。

ps:由于原表的日期具体到了年月日,但是我们是看年月,所以在进行上面一系列操作前要先用DATE_FORMAT()函数获取日期的年月,再根据年月进行分组,具体写法:DATE_FORMAT(pay_date,'%Y-%m')

SELECT t.pay_month, t.department_id,
CASE WHEN t.avg_de>t.avg_month THEN 'higher'
WHEN t.avg_de=t.avg_month THEN 'same'
WHEN t.avg_de<t.avg_month THEN 'lower'
END AS comparison
FROM(
SELECT DISTINCT b.department_id, a.pay_month,
AVG(a.amount) OVER(PARTITION BY a.pay_month, b.department_id) AS avg_de,
AVG(a.amount) OVER(PARTITION BY a.pay_month) AS avg_month
FROM
(
SELECT id, employee_id, amount, DATE_FORMAT(pay_date,'%Y-%m') AS pay_month FROM salary
) a
LEFT JOIN employee b ON a.employee_id=b.employee_id
) t

 618. 学生地理信息报告

https://leetcode-cn.com/problems/students-report-by-geography/

一所美国大学有来自亚洲、欧洲和美洲的学生,他们的地理信息存放在如下 student 表中。

 

| name   | continent |
|--------|-----------|
| Jack   | America   |
| Pascal | Europe    |
| Xi     | Asia      |
| Jane   | America   |
 

写一个查询语句实现对大洲(continent)列的 透视表 操作,使得每个学生按照姓名的字母顺序依次排列在对应的大洲下面。输出的标题应依次为美洲(America)、亚洲(Asia)和欧洲(Europe)。

 

对于样例输入,它的对应输出是:

 

| America | Asia | Europe |
|---------|------|--------|
| Jack    | Xi   | Pascal |
| Jane    |      |        |
 

进阶:如果不能确定哪个大洲的学生数最多,你可以写出一个查询去生成上述学生报告吗?

思路:分别取出原表中属于三个大洲的学生名字作为三张子表a,b,c,且表中包含学生的序号(按名字排序),对三张表按序号依次进行LEFT JOIN。 

SELECT a.America, b.Asia, c.Europe
FROM
(
SELECT name AS America, ROW_NUMBER() OVER(ORDER BY name) AS rk
FROM student
WHERE continent='America'
) a
LEFT JOIN
(
SELECT name AS Asia, ROW_NUMBER() OVER(ORDER BY name) AS rk
FROM student
WHERE continent='Asia'
) b
ON a.rk=b.rk
LEFT JOIN
(
SELECT name AS Europe, ROW_NUMBER() OVER(ORDER BY name) AS rk
FROM student
WHERE continent='Europe'
) c
ON a.rk=c.rk

 619. 只出现一次的最大数字

https://leetcode-cn.com/problems/biggest-single-number/

表 my_numbers 的 num 字段包含很多数字,其中包括很多重复的数字。

你能写一个 SQL 查询语句,找到只出现过一次的数字中,最大的一个数字吗?

+---+
|num|
+---+
| 8 |
| 8 |
| 3 |
| 3 |
| 1 |
| 4 |
| 5 |
| 6 | 
对于上面给出的样例数据,你的查询语句应该返回如下结果:

+---+
|num|
+---+
| 6 |
注意:

如果没有只出现一次的数字,输出 null 。

思路:分组计算每个数字出现的次数 ,取出次数为1的数字中最大的那一个

SELECT MAX(num) AS num
FROM
(
SELECT DISTINCT num, COUNT(*) OVER(PARTITION BY num) AS cnt
FROM my_numbers
) t
WHERE t.cnt=1

 620. 有趣的电影

https://leetcode-cn.com/problems/not-boring-movies/

某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 LED显示板做电影推荐,上面公布着影评和相关电影描述。

作为该电影院的信息部主管,您需要编写一个 SQL查询,找出所有影片描述为非 boring (不无聊) 的并且 id 为奇数 的影片,结果请按等级 rating 排列。

 

例如,下表 cinema:

+---------+-----------+--------------+-----------+
|   id    | movie     |  description |  rating   |
+---------+-----------+--------------+-----------+
|   1     | War       |   great 3D   |   8.9     |
|   2     | Science   |   fiction    |   8.5     |
|   3     | irish     |   boring     |   6.2     |
|   4     | Ice song  |   Fantacy    |   8.6     |
|   5     | House card|   Interesting|   9.1     |
+---------+-----------+--------------+-----------+
对于上面的例子,则正确的输出是为:

+---------+-----------+--------------+-----------+
|   id    | movie     |  description |  rating   |
+---------+-----------+--------------+-----------+
|   5     | House card|   Interesting|   9.1     |
|   1     | War       |   great 3D   |   8.9     |
+---------+-----------+--------------+-----------+

思路:直接用where写两个条件,description!='boring'且id mod 2!=0,再根据rating降序排序就可以了。 

SELECT *
FROM cinema
WHERE description!='boring' AND id mod 2!=0
ORDER BY rating DESC

 626. 换座位

https://leetcode-cn.com/problems/exchange-seats/

小美是一所中学的信息科技老师,她有一张 seat 座位表,平时用来储存学生名字和与他们相对应的座位 id。

其中纵列的 id 是连续递增的

小美想改变相邻俩学生的座位。

你能不能帮她写一个 SQL query 来输出小美想要的结果呢?

 

示例:

+---------+---------+
|    id   | student |
+---------+---------+
|    1    | Abbot   |
|    2    | Doris   |
|    3    | Emerson |
|    4    | Green   |
|    5    | Jeames  |
+---------+---------+
假如数据输入的是上表,则输出结果如下:

+---------+---------+
|    id   | student |
+---------+---------+
|    1    | Doris   |
|    2    | Abbot   |
|    3    | Green   |
|    4    | Emerson |
|    5    | Jeames  |
+---------+---------+
注意:

如果学生人数是奇数,则不需要改变最后一个同学的座位。

思路:用LEFT JOIN做原表自连接,连接的匹配条件有两种:左表的id为奇数时应连上其在右表的后一行,或者,左表的id为偶数时应连上其在右表的前一行,这样就完成了相邻位置的调换,连接后的右表即为调换后的学生顺序,取出座位id和右表学生名字即可。

SELECT a.id, IFNULL(b.student, a.student) AS student
FROM seat a LEFT JOIN seat b
ON (a.id mod 2!=0 AND a.id=b.id-1) OR (a.id mod 2=0 AND a.id=b.id+1)

 627. 变更性别

https://leetcode-cn.com/problems/swap-salary/

给定一个 salary 表,如下所示,有 m = 男性 和 f = 女性 的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求只使用一个更新(Update)语句,并且没有中间的临时表。

注意,您必只能写一个 Update 语句,请不要编写任何 Select 语句。

例如:

| id | name | sex | salary |
|----|------|-----|--------|
| 1  | A    | m   | 2500   |
| 2  | B    | f   | 1500   |
| 3  | C    | m   | 5500   |
| 4  | D    | f   | 500    |
运行你所编写的更新语句之后,将会得到以下表:

| id | name | sex | salary |
|----|------|-----|--------|
| 1  | A    | f   | 2500   |
| 2  | B    | m   | 1500   |
| 3  | C    | f   | 5500   |
| 4  | D    | m   | 500    |

思路:在SET 那里用IF条件语句判断给sex赋'm'值还是'f'值 

Update salary SET sex=IF(sex='m', 'f', 'm')

 

最后

以上就是飞快店员为你收集整理的Leetcode|MySQL|数据库刷题记录(601~627)601. 体育馆的人流量602. 好友申请 II :谁有最多的好友603. 连续空余座位 607. 销售员 608. 树节点 610. 判断三角形 612. 平面上的最近距离 613. 直线上的最近距离 614. 二级关注者615. 平均工资:部门与公司比较 618. 学生地理信息报告 619. 只出现一次的最大数字 620. 有趣的电影 626. 换座位 627. 变更性别的全部内容,希望文章能够帮你解决Leetcode|MySQL|数据库刷题记录(601~627)601. 体育馆的人流量602. 好友申请 II :谁有最多的好友603. 连续空余座位 607. 销售员 608. 树节点 610. 判断三角形 612. 平面上的最近距离 613. 直线上的最近距离 614. 二级关注者615. 平均工资:部门与公司比较 618. 学生地理信息报告 619. 只出现一次的最大数字 620. 有趣的电影 626. 换座位 627. 变更性别所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部