LeetCode_Database

寻找用户推荐人

题目描述

表: Customer

±------------±--------+
| Column Name | Type |
±------------±--------+
| id | int |
| name | varchar |
| referee_id | int |
±------------±--------+
在 SQL 中,id 是该表的主键列。
该表的每一行表示一个客户的 id、姓名以及推荐他们的客户的 id。
找出那些 没有被 id = 2 的客户 推荐 的客户的姓名。

以 任意顺序 返回结果表。

结果格式如下所示。

示例 1:

输入:
Customer 表:

+----+------+------------+
| id | name | referee_id |
+----+------+------------+
| 1  | Will | null       |
| 2  | Jane | null       |
| 3  | Alex | 2          |
| 4  | Bill | null       |
| 5  | Zack | 1          |
| 6  | Mark | 2          |
+----+------+------------+

输出:

+------+
| name |
+------+
| Will |
| Jane |
| Bill |
| Zack |
+------+

解题

select name from Customer where referee_id != 2 OR referee_id IS NULL;

MySQL 使用三值逻辑 —— TRUE, FALSE 和 UNKNOWN。任何与 NULL 值进行的比较都会与第三种值 UNKNOWN 做比较。这个“任何值”包括 NULL 本身!这就是为什么 MySQL 提供 IS NULL 和 IS NOT NULL 两种操作来对 NULL 特殊判断。

因此,在 WHERE 语句中我们需要做一个额外的条件判断 `referee_id IS NULL’。

无效的推文

题目描述

表:Tweets

+----------------+---------+
| Column Name    | Type    |
+----------------+---------+
| tweet_id       | int     |
| content        | varchar |
+----------------+---------+

在 SQL 中,tweet_id 是这个表的主键。
这个表包含某社交媒体 App 中所有的推文。

查询所有无效推文的编号(ID)。当推文内容中的字符数严格大于 15 时,该推文是无效的。

以任意顺序返回结果表。

查询结果格式如下所示:

示例 1:

输入:
Tweets 表:

+----------+----------------------------------+
| tweet_id | content                          |
+----------+----------------------------------+
| 1        | Vote for Biden                   |
| 2        | Let us make America great again! |
+----------+----------------------------------+

输出:

+----------+
| tweet_id |
+----------+
| 2        |
+----------+

解释:
推文 1 的长度 length = 14。该推文是有效的。
推文 2 的长度 length = 32。该推文是无效的。

解题

select tweet_id from Tweets where CHAR_LENGTH(content) > 15;

1 组合两个表

题目描述

表1: Person

+-------------+---------+
| 列名         | 类型     |
+-------------+---------+
| PersonId    | int     |
| FirstName   | varchar |
| LastName    | varchar |
+-------------+---------+
PersonId 是上表主键

表2: Address

+-------------+---------+
| 列名         | 类型    |
+-------------+---------+
| AddressId   | int     |
| PersonId    | int     |
| City        | varchar |
| State       | varchar |
+-------------+---------+
AddressId 是上表主键

编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:

FirstName, LastName, City, State

SQL Schema

DROP TABLE IF EXISTS Person;

CREATE TABLE Person (
  PersonId INT,
  FirstName VARCHAR(255),
  LastName VARCHAR(255)
);

DROP TABLE IF EXISTS Address;

CREATE TABLE Address (
  AddressId INT,
  PersonId INT,
  City VARCHAR(255),
  State VARCHAR(255)
);

INSERT INTO
  Person(PersonId, LastName, FirstName)
VALUES
  (1, 'Wang', 'Allen');

INSERT INTO
  Address(AddressId, PersonId, City, State)
VALUES
  (1, 2, 'New York City', 'New York');

解题

# 思路:左外连接
SELECT
    p.FirstName,
    p.LastName,
    a.City,
    a.State
FROM
    Person p LEFT JOIN Address a 
    ON p.PersonId = a.PersonId;

2 第二高的薪水

题目描述

编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。

+----+--------+
| Id | Salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+

例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。

+---------------------+
| SecondHighestSalary |
+---------------------+
| 200                 |
+---------------------+

SQL Schema

DROP TABLE IF EXISTS Employee;

CREATE TABLE Employee (
  Id INT, 
  Salary INT
);

INSERT INTO
  Employee (Id, Salary)
VALUES
  (1, 100),
  (2, 200),
  (3, 300);

解题

# 查询所有 salary 按照降序排列
SELECT
  DISTINCT Salary
FROM
  Employee
ORDER BY
  Salary DESC;
# 要获取第二高的的薪水,就是获取第二个元素,
# 使用  limit start,count; start:开始查询的位置,count 是查询多少条语句
SELECT
  DISTINCT Salary
FROM
  Employee
ORDER BY
  Salary DESC
LIMIT
  1, 1;
# Write your MySQL query statement below
SELECT 
    (
    SELECT
        DISTINCT Salary 
    FROM  
        Employee
    ORDER BY 
        Salary DESC
    LIMIT
        1, 1
    ) SecondHighestSalary

3 第N高的薪水

题目描述

编写一个 SQL 查询,获取 Employee 表中第 n 高的薪水(Salary)。

+----+--------+
| Id | Salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+

例如上述 Employee 表,n = 2 时,应返回第二高的薪水 200。如果不存在第 n 高的薪水,那么查询应返回 null,因此再嵌套一层子查询。

+------------------------+
| getNthHighestSalary(2) |
+------------------------+
| 200                    |
+------------------------+

解题

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
    # 注意 LIMIT 的 start 是从 0 开始的,第 N 实际上是第 (N-1)
    SET
        N = N - 1;
    RETURN 
    (
        SELECT
            DISTINCT Salary
        FROM
            Employee
        ORDER BY
            Salary DESC
        LIMIT
            N, 1
    );
END

4 分数排名

题目描述

编写一个 SQL 查询来实现分数排名。

如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。

+----+-------+
| Id | Score |
+----+-------+
| 1  | 3.50  |
| 2  | 3.65  |
| 3  | 4.00  |
| 4  | 3.85  |
| 5  | 4.00  |
| 6  | 3.65  |
+----+-------+

例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):

+-------+------+
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 2    |
| 3.65  | 3    |
| 3.65  | 3    |
| 3.50  | 4    |
+-------+------+

**重要提示:**对于 MySQL 解决方案,如果要转义用作列名的保留字,可以在关键字之前和之后使用撇号。例如 Rank

SQL Schema

DROP TABLE IF EXISTS Scores;

CREATE TABLE Scores
(
   Id INT,
   Score DECIMAL(3, 2)
);

INSERT INTO
  Scores(Id, Score)
VALUES
  (1, 3.5),
  (2, 3.65),
  (3, 4.0),
  (4, 3.85),
  (5, 4.0),
  (6, 3.65);

解题

SELECT
    a.Score AS Score,
    (
    SELECT 
        COUNT(DISTINCT b.Score)
    FROM
        Scores b 
    WHERE
        b.Score >= a.Score 
    ) AS 'Rank'# 由于Rank为关键字,所以必须加``
FROM
    Scores a 
ORDER BY
    a.Score DESC

5 连续出现的数字

题目描述

编写一个 SQL 查询,查找所有至少连续出现三次的数字。

+----+-----+
| Id | Num |
+----+-----+
| 1  |  1  |
| 2  |  1  |
| 3  |  1  |
| 4  |  2  |
| 5  |  1  |
| 6  |  2  |
| 7  |  2  |
+----+-----+

例如,给定上面的 Logs 表, 1 是唯一连续出现至少三次的数字。

+-----------------+
| ConsecutiveNums |
+-----------------+
| 1               |
+-----------------+

SQL Schema

DROP TABLE IF EXISTS LOGS;

CREATE TABLE LOGS 
(
  Id INT,
  Num INT 
);

INSERT INTO
  LOGS (Id, Num)
VALUES
  (1, 1),
  (2, 1),
  (3, 1),
  (4, 2),
  (5, 1),
  (6, 2),
  (7, 2);

解题

# 思路:要求是连续出现 3 次,可使用 3 张该表
# 判断条件 Id 是不相同的,但是 Num 是相同的,并且 Id 是连续变化的
# 需要 DISTINCT 进行去重
SELECT
    DISTINCT L1.Num ConsecutiveNums
FROM
    Logs L1,
    Logs L2,
    Logs L3
WHERE
    L2.Id = L1.Id + 1
    AND L3.Id = L2.Id + 1
    AND L2.Num = L1.Num
    AND L3.Num = L2.Num;

6 超过经理收入的员工

题目描述

Employee 表包含所有员工,他们的经理也属于员工。每个员工都有一个 Id,此外还有一列对应员工的经理的 Id。

+----+-------+--------+-----------+
| Id | Name  | Salary | ManagerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | NULL      |
| 4  | Max   | 90000  | NULL      |
+----+-------+--------+-----------+

给定 Employee 表,编写一个 SQL 查询,该查询可以获取收入超过他们经理的员工的姓名。在上面的表格中,Joe 是唯一一个收入超过他的经理的员工。

+----------+
| Employee |
+----------+
| Joe      |
+----------+

SQL Schema

DROP TABLE IF EXISTS Employee;

CREATE TABLE Employee (
  Id INT,
  Name VARCHAR(255),
  Salary INT,
  ManagerId INT
);

INSERT INTO
  Employee (Id, NAME, Salary, ManagerId)
VALUES
  (1, 'Joe', 70000, 3),
  (2, 'Henry', 80000, 4),
  (3, 'Sam', 60000, NULL),
  (4, 'Max', 90000, NULL);

解题

# 思路:Employee e1 INNER JOIN Employee e2 ON e1.managerid = e2.id 比如
+----+-------+--------+-----------+
| Id | Name  | Salary | ManagerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | NULL      |
| 4  | Max   | 90000  | NULL      |
+----+-------+--------+-----------+

根据 e1.managerid = e2.id 条件进行内连接后,得到

+----+-------+--------+-----------+-------+--------+-----------+
| Id | Name  | Salary | ManagerId | Name  | Salary | ManagerId |
+----+-------+--------+-----------+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         | Sam   | 60000  | NULL      |
| 2  | Henry | 80000  | 4         | Max   | 90000  | NULL      |
+----+-------+--------+-----------+-------+--------+-----------+
SELECT
    e1.Name AS Employee
FROM
    Employee e1, Employee e2
WHERE
    e1.ManagerId = e2.id
    AND e1.Salary > e2.Salary;

7 查找重复的电子邮箱

题目描述

编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。

示例:

+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+

根据以上输入,你的查询应返回以下结果:

+---------+
| Email   |
+---------+
| a@b.com |
+---------+
  • 说明:所有电子邮箱都是小写字母。

SQL Schema

DROP TABLE IF EXISTS Person;

CREATE TABLE Person
(
  Id INT, 
  Email VARCHAR(255)
);

INSERT INTO
  Person (Id, Email)
VALUES
  (1, 'a@b.com'),
  (2, 'c@d.com'),
  (3, 'a@b.com');

解题

# 思路:与前题类似
# 1、按照 mail 进行分组
# 2、统计出现次数 >=2 就是重复的邮件
SELECT
    Email
FROM
    Person
GROUP BY
    Email
HAVING
    COUNT(Id) >= 2;

8 从不订购的客户

题目描述

某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。

Customers 表:

+----+-------+
| Id | Name  |
+----+-------+
| 1  | Joe   |
| 2  | Henry |
| 3  | Sam   |
| 4  | Max   |
+----+-------+

Orders 表:

+----+------------+
| Id | CustomerId |
+----+------------+
| 1  | 3          |
| 2  | 1          |
+----+------------+

例如给定上述表格,你的查询应返回:

+-----------+
| Customers |
+-----------+
| Henry     |
| Max       |
+-----------+

SQL Schema

DROP TABLE IF EXISTS Customers;

CREATE TABLE Customers 
(
  Id INT, 
  Name VARCHAR(255)
);

DROP TABLE IF EXISTS Orders;

CREATE TABLE Orders 
(
  Id INT, 
  CustomerId INT 
);

INSERT INTO
  Customers(Id, NAME)
VALUES
  (1, 'Joe'),
  (2, 'Henry'),
  (3, 'Sam'),
  (4, 'Max');

INSERT INTO
  Orders(Id, CustomerId)
VALUES
  (1, 3),
  (2, 1);

解题

# 解法一:左外连接
SELECT
    Name AS Customers
FROM
    Customers LEFT JOIN Orders
    ON Customers.Id = Orders.CustomerId
WHERE
    Orders.CustomerId IS NULL;
# 解法二:子查询方式
SELECT
    Name AS Customers
FROM
    Customers
WHERE
    Id NOT IN 
    (
    SELECT
        CustomerId
    FROM
        Orders
    );

9 部门工资最高的员工

题目描述

Employee 表包含所有员工信息,每个员工有其对应的 Id, Salary 和 DepartmentId。

+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+

Department 表包含公司所有部门的信息。

+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+

编写一个 SQL 查询,找出每个部门工资最高的员工。对于上述表,您的 SQL 查询应返回以下行(行的顺序无关紧要)。

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Jim      | 90000  |
| Sales      | Henry    | 80000  |
+------------+----------+--------+

解释:

  • Max 和 Jim 在 IT 部门的工资都是最高的,Henry 在销售部的工资最高。

SQL Schema

DROP TABLE IF EXISTS Employee;

CREATE TABLE Employee 
(
  Id INT,
  Name VARCHAR(255),
  Salary INT,
  DepartmentId INT
);

DROP TABLE IF EXISTS Department;

CREATE TABLE Department
(
  Id INT,
  Name VARCHAR(255)
);

INSERT INTO
  Employee(Id, Name, Salary, DepartmentId)
VALUES
  (1, 'Joe', 70000, 1),
  (2, 'Henry', 80000, 2),
  (3, 'Sam', 60000, 2),
  (4, 'Max', 90000, 1);

INSERT INTO
  Department(Id, Name)
VALUES
  (1, 'IT'),
  (2, 'Sales');

解题

# 创建一个临时表,包含了部门员工的最大薪资。
SELECT
	DepartmentId,
	MAX(Salary) Salary
FROM
	Employee
GROUP BY
	DepartmentId;

# 结果:
+--------------+--------+
| DepartmentId | Salary |
+--------------+--------+
|            1 |  90000 |
|            2 |  80000 |
+--------------+--------+

使用连接找到一个部门中薪资等于临时表中最大薪资的员工。

SELECT
    d.Name as Department,
    e.Name as Employee,
    m.Salary
FROM
    Employee e,
    Department d,
    (
    SELECT
        DepartmentId,
        MAX(Salary) Salary
    FROM
        Employee
    GROUP BY
        DepartmentId
    ) m
WHERE
    e.DepartmentId = m.DepartmentId
    AND e.Salary = m.Salary
    AND d.Id = e.DepartmentId;

10 删除重复的电子邮箱

题目描述

编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
| 3  | john@example.com |
+----+------------------+

Id 是这个表的主键。
例如,在运行你的查询语句之后,上面的 Person 表应返回以下几行:

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
+----+------------------+

提示:

  • 执行 SQL 之后,输出是整个 Person 表。
  • 使用 delete 语句。

解题

思路一

# 思路一:将一张表看成两张表来进行操作
DELETE
	p1
FROM
    Person p1,
    Person p2
WHERE
    p1.Email = p2.Email
    AND p1.Id > p2.Id

思路二

# 思路二:
# 第一步:根据 email 进行分组,获取 email 对应的最小 id,一个 email 对应一个最小的 id
SELECT MIN(Id) AS Id FROM Person GROUP BY Email;

# 第二步:删除不在该 id 集合中的数据
DELETE
FROM
    Person
WHERE
    Id NOT IN
    ( 
    SELECT 
        Id 
    FROM
        (
        SELECT 
            MIN(Id) AS Id
        FROM
            Person
        GROUP BY
            Email
        ) m
    );
# 应该注意的是上述解法额外嵌套了一个 SELECT 语句。
# 如果不这么做,会出现错误:You can't specify target table 'Person' for update in FROM clause。

11 大的国家

题目描述

这里有张 World 表

+-----------------+------------+------------+--------------+---------------+
| name            | continent  | area       | population   | gdp           |
+-----------------+------------+------------+--------------+---------------+
| Afghanistan     | Asia       | 652230     | 25500100     | 20343000      |
| Albania         | Europe     | 28748      | 2831741      | 12960000      |
| Algeria         | Africa     | 2381741    | 37100000     | 188681000     |
| Andorra         | Europe     | 468        | 78115        | 3712000       |
| Angola          | Africa     | 1246700    | 20609294     | 100990000     |
+-----------------+------------+------------+--------------+---------------+

如果一个国家的面积超过 300 万平方公里,或者人口超过 2500 万,那么这个国家就是大国家。

编写一个 SQL 查询,输出表中所有大国家的名称、人口和面积。

例如,根据上表,我们应该输出:

+--------------+-------------+--------------+
| name         | population  | area         |
+--------------+-------------+--------------+
| Afghanistan  | 25500100    | 652230       |
| Algeria      | 37100000    | 2381741      |
+--------------+-------------+--------------+

SQL Schema

DROP TABLE IF EXISTS World;
CREATE TABLE World
(
  name VARCHAR(255), 
  continent VARCHAR(255), 
  area INT, 
  population INT, 
  gdp INT
);
INSERT INTO
  World (name, continent, area, population, gdp)
VALUES
  ('Afghanistan', 'Asia', '652230', '25500100', '203430000'),
  ('Albania', 'Europe', '28748', '2831741', '129600000'),
  ('Algeria', 'Africa', '2381741', '37100000', '1886810000'),
  ('Andorra', 'Europe', '468', '78115', '37120000'),
  ('Angola', 'Africa', '1246700', '20609294', '1009900000');

解题

# 思路:
# 1、根据样例,我们知道。查询字段是 name population 和 area
# 2、查询条件是 area > 3000000 || population > 25000000
SELECT 
    name,population,area
FROM
    World 
WHERE
    area > 3000000 
    OR population > 25000000;

12 超过5名学生的课

题目描述

有一个courses 表 ,有: student (学生) 和 class (课程)。

请列出所有超过或等于5名学生的课。

例如,表:

+---------+------------+
| student | class      |
+---------+------------+
| A       | Math       |
| B       | English    |
| C       | Math       |
| D       | Biology    |
| E       | Math       |
| F       | Computer   |
| G       | Math       |
| H       | Math       |
| I       | Math       |
+---------+------------+

应该输出:

+---------+
| class   |
+---------+
| Math    |
+---------+

提示:

  • 学生在每个课中不应被重复计算。

SQL Schema

DROP TABLE IF EXISTS courses;
CREATE TABLE courses
(
  student VARCHAR(255), 
  class VARCHAR(255)
);
INSERT INTO 
  courses(student, class)
VALUES
    ( 'A', 'Math' ),
    ( 'B', 'English' ),
    ( 'C', 'Math' ),
    ( 'D', 'Biology' ),
    ( 'E', 'Math' ),
    ( 'F', 'Computer' ),
    ( 'G', 'Math' ),
    ( 'H', 'Math' ),
    ( 'I', 'Math' );

解题

# 思路:
# 1、很显然要按照 class 进行分组
# 2、然后按照分组后的 class 来统计学生的人数
SELECT
    class
FROM
    courses
GROUP BY
    class
HAVING
    COUNT(DISTINCT student) >= 5;

13 有趣的电影

题目描述

某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 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     |
+---------+-----------+--------------+-----------+

SQL Schema

DROP TABLE IF EXISTS cinema;

CREATE TABLE cinema 
(
  id INT, 
  movie VARCHAR(255), 
  description VARCHAR(255), 
  rating FLOAT(2,1)
);

INSERT INTO 
  cinema(id, movie, description, rating)
VALUES
    (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);

解题

#思路:
#1、观察测试用例的查询结果,我们知道,其实查询的是所有的字段
#2、id 为奇数,则查询条件为 id % 2 = 1
SELECT
    id,movie,description,rating
FROM
    cinema
WHERE
    id % 2 = 1 
    AND description != 'boring'
ORDER BY
    rating DESC;

14 换座位

题目描述

小美是一所中学的信息科技老师,她有一张 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  |
+---------+---------+

注意:

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

SQL Schema

DROP TABLE IF EXISTS seat;
CREATE TABLE seat
(
  id INT, 
  student VARCHAR(255)
);
INSERT INTO 
  seat(id, student)
VALUES
  ('1', 'Abbot'),
  ('2', 'Doris'),
  ('3', 'Emerson'),
  ('4', 'Green'),
  ('5', 'Jeames');

解题

# 对于所有座位 id 是奇数的学生,修改其 id 为 id+1,如果最后一个座位 id 也是奇数,则最后一个座位 id 不修改。
# 对于所有座位 id 是偶数的学生,修改其 id 为 id-1。
SELECT
    (
    CASE
        WHEN MOD(id, 2) = 0 THEN id - 1
        WHEN MOD(id, 2) != 0 AND id != counts THEN id + 1
        ELSE id
    END
    ) AS id,
    student
FROM
    seat,
    (
    SELECT
        COUNT(*) AS counts
    FROM
        seat
    ) AS seat_counts
ORDER BY
    id ASC;

15 变更性别

题目描述

给定一个 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    |

SQL Schema

DROP TABLE IF EXISTS salary;
CREATE TABLE salary 
(
  id INT,
  NAME VARCHAR(100),
  sex CHAR(1),
  salary INT
);
INSERT INTO 
  salary(id, NAME, sex, salary)
VALUES
  ('1', 'A', 'm', '2500'),
  ('2', 'B', 'f', '1500'),
  ('3', 'C', 'm', '5500'),
  ('4', 'D', 'f', '500');

解题

# 思路:
# l、利用位运算:若x = a,则x ^ b ^ a = b;若x = b,则x ^ b ^ a = a;
# 2、利用 ASCII 函数将字符转换为数值进行运算,然后再利用 CHAR 函数将数值转换为字符
UPDATE 
    salary
SET
    sex = CHAR(ASCII(sex) ^ ASCII('m') ^ ASCII('f'));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hellosc01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值