LeetCode MySQL 50 速刷题解 · MySQL

LeetCode MySQL 50 速刷题解

用途:暑假面试前快速恢复 MySQL 上机手感。
说明:本文不复制 LeetCode 原题正文,只保留题号、标题、官方链接、中文题意概述、常见表和 MySQL 参考答案。表名/字段名按 LeetCode SQL 50 常见版本整理,遇到平台字段版本微调时以在线题面为准。

速刷顺序

分组题量重点
Select5基础筛选、去重、排序、字符串长度
Basic Joins9LEFT JOIN、自连接、笛卡尔积补零
Basic Aggregate Functions8GROUP BY、比例、条件聚合、首日留存
Sorting and Grouping7去重计数、最大唯一值、集合覆盖
Advanced Select and Joins7CASE、窗口函数、默认值、累计和
Subqueries7子查询、UNION ALL、Top N、移动窗口
Advanced String Functions / Regex / Clause7字符串函数、正则、删除重复行

Select

1757. Recyclable and Low Fat Products

  • 官方链接:1757
  • 题意概述:从 Products 中找出低脂且可回收的商品。
  • 常见表:Products(product_id, low_fats, recyclable)
  • 考点:WHERE 多条件筛选。
代码块SQL · 4 行收起展开
SELECT product_id
FROM Products
WHERE low_fats = 'Y'
  AND recyclable = 'Y';

584. Find Customer Referee

  • 官方链接:584
  • 题意概述:找出推荐人不是 2 的客户,推荐人为空也要保留。
  • 常见表:Customer(id, name, referee_id)
  • 考点:NULL 不能用 <> 直接覆盖。
代码块SQL · 4 行收起展开
SELECT name
FROM Customer
WHERE referee_id <> 2
   OR referee_id IS NULL;

595. Big Countries

  • 官方链接:595
  • 题意概述:找出面积大或人口多的国家。
  • 常见表:World(name, continent, area, population, gdp)
  • 考点:OR 条件。
代码块SQL · 4 行收起展开
SELECT name, population, area
FROM World
WHERE area >= 3000000
   OR population >= 25000000;

1148. Article Views I

  • 官方链接:1148
  • 题意概述:找出看过自己文章的作者。
  • 常见表:Views(article_id, author_id, viewer_id, view_date)
  • 考点:DISTINCT、按结果列排序。
代码块SQL · 4 行收起展开
SELECT DISTINCT author_id AS id
FROM Views
WHERE author_id = viewer_id
ORDER BY id;

1683. Invalid Tweets

  • 官方链接:1683
  • 题意概述:找出内容长度超过 15 的推文。
  • 常见表:Tweets(tweet_id, content)
  • 考点:CHAR_LENGTH()
代码块SQL · 3 行收起展开
SELECT tweet_id
FROM Tweets
WHERE CHAR_LENGTH(content) > 15;

Basic Joins

1378. Replace Employee ID With The Unique Identifier

  • 官方链接:1378
  • 题意概述:用员工唯一编号替换普通员工 id,没有唯一编号时显示 NULL
  • 常见表:Employees(id, name)EmployeeUNI(id, unique_id)
  • 考点:保留全部员工,用 LEFT JOIN
代码块SQL · 4 行收起展开
SELECT u.unique_id, e.name
FROM Employees e
LEFT JOIN EmployeeUNI u
  ON e.id = u.id;

1068. Product Sales Analysis I

  • 官方链接:1068
  • 题意概述:展示每条销售记录对应的商品名、年份和价格。
  • 常见表:Sales(sale_id, product_id, year, quantity, price)Product(product_id, product_name)
  • 考点:基础内连接。
代码块SQL · 4 行收起展开
SELECT p.product_name, s.year, s.price
FROM Sales s
JOIN Product p
  ON s.product_id = p.product_id;

1581. Customer Who Visited but Did Not Make Any Transactions

  • 官方链接:1581
  • 题意概述:统计只访问但没有交易的客户访问次数。
  • 常见表:Visits(visit_id, customer_id)Transactions(transaction_id, visit_id, amount)
  • 考点:反连接 LEFT JOIN ... IS NULL
代码块SQL · 7 行收起展开
SELECT v.customer_id,
       COUNT(*) AS count_no_trans
FROM Visits v
LEFT JOIN Transactions t
  ON v.visit_id = t.visit_id
WHERE t.transaction_id IS NULL
GROUP BY v.customer_id;

197. Rising Temperature

  • 官方链接:197
  • 题意概述:找出比前一天温度更高的日期 id。
  • 常见表:Weather(id, recordDate, temperature)
  • 考点:日期相差一天的自连接。
代码块SQL · 5 行收起展开
SELECT w1.id
FROM Weather w1
JOIN Weather w2
  ON DATEDIFF(w1.recordDate, w2.recordDate) = 1
WHERE w1.temperature > w2.temperature;

1661. Average Time of Process per Machine

  • 官方链接:1661
  • 题意概述:每台机器的平均处理时间等于同一进程结束时间减开始时间。
  • 常见表:Activity(machine_id, process_id, activity_type, timestamp)
  • 考点:同表按 start/end 配对。
代码块SQL · 9 行收起展开
SELECT a1.machine_id,
       ROUND(AVG(a2.timestamp - a1.timestamp), 3) AS processing_time
FROM Activity a1
JOIN Activity a2
  ON a1.machine_id = a2.machine_id
 AND a1.process_id = a2.process_id
 AND a1.activity_type = 'start'
 AND a2.activity_type = 'end'
GROUP BY a1.machine_id;

577. Employee Bonus

  • 官方链接:577
  • 题意概述:找出奖金小于 1000 或没有奖金记录的员工。
  • 常见表:Employee(empId, name, supervisor, salary)Bonus(empId, bonus)
  • 考点:LEFT JOIN 后处理 NULL
代码块SQL · 6 行收起展开
SELECT e.name, b.bonus
FROM Employee e
LEFT JOIN Bonus b
  ON e.empId = b.empId
WHERE b.bonus < 1000
   OR b.bonus IS NULL;

1280. Students and Examinations

  • 官方链接:1280
  • 题意概述:列出每个学生每门科目的参加考试次数,没有参加则为 0。
  • 常见表:Students(student_id, student_name)Subjects(subject_name)Examinations(student_id, subject_name)
  • 考点:CROSS JOIN 造完整组合,再 LEFT JOIN 补零。
代码块SQL · 11 行收起展开
SELECT s.student_id,
       s.student_name,
       sub.subject_name,
       COUNT(e.subject_name) AS attended_exams
FROM Students s
CROSS JOIN Subjects sub
LEFT JOIN Examinations e
  ON s.student_id = e.student_id
 AND sub.subject_name = e.subject_name
GROUP BY s.student_id, s.student_name, sub.subject_name
ORDER BY s.student_id, sub.subject_name;

570. Managers with at Least 5 Direct Reports

  • 官方链接:570
  • 题意概述:找出直属下属至少 5 人的经理。
  • 常见表:Employee(id, name, department, managerId)
  • 考点:员工表自连接后分组。
代码块SQL · 6 行收起展开
SELECT m.name
FROM Employee e
JOIN Employee m
  ON e.managerId = m.id
GROUP BY m.id, m.name
HAVING COUNT(*) >= 5;

1934. Confirmation Rate

  • 官方链接:1934
  • 题意概述:计算每个用户确认动作占全部确认请求的比例,没有请求则为 0。
  • 常见表:Signups(user_id, time_stamp)Confirmations(user_id, time_stamp, action)
  • 考点:布尔表达式求平均、IFNULL
代码块SQL · 6 行收起展开
SELECT s.user_id,
       ROUND(IFNULL(AVG(c.action = 'confirmed'), 0), 2) AS confirmation_rate
FROM Signups s
LEFT JOIN Confirmations c
  ON s.user_id = c.user_id
GROUP BY s.user_id;

Basic Aggregate Functions

620. Not Boring Movies

  • 官方链接:620
  • 题意概述:找出 id 为奇数且描述不是 boring 的电影,并按评分降序。
  • 常见表:Cinema(id, movie, description, rating)
  • 考点:取模、排序。
代码块SQL · 5 行收起展开
SELECT id, movie, description, rating
FROM Cinema
WHERE id % 2 = 1
  AND description <> 'boring'
ORDER BY rating DESC;

1251. Average Selling Price

  • 官方链接:1251
  • 题意概述:按商品计算加权平均售价,没有销量则为 0。
  • 常见表:Prices(product_id, start_date, end_date, price)UnitsSold(product_id, purchase_date, units)
  • 考点:区间连接、加权平均。
代码块SQL · 7 行收起展开
SELECT p.product_id,
       IFNULL(ROUND(SUM(u.units * p.price) / SUM(u.units), 2), 0) AS average_price
FROM Prices p
LEFT JOIN UnitsSold u
  ON p.product_id = u.product_id
 AND u.purchase_date BETWEEN p.start_date AND p.end_date
GROUP BY p.product_id;

1075. Project Employees I

  • 官方链接:1075
  • 题意概述:计算每个项目员工平均工作年限。
  • 常见表:Project(project_id, employee_id)Employee(employee_id, name, experience_years)
  • 考点:连接后聚合。
代码块SQL · 6 行收起展开
SELECT p.project_id,
       ROUND(AVG(e.experience_years), 2) AS average_years
FROM Project p
JOIN Employee e
  ON p.employee_id = e.employee_id
GROUP BY p.project_id;

1633. Percentage of Users Attended a Contest

  • 官方链接:1633
  • 题意概述:计算每场比赛参加用户占总用户数的百分比。
  • 常见表:Users(user_id, user_name)Register(contest_id, user_id)
  • 考点:分母用总用户数子查询。
代码块SQL · 5 行收起展开
SELECT r.contest_id,
       ROUND(COUNT(DISTINCT r.user_id) * 100 / (SELECT COUNT(*) FROM Users), 2) AS percentage
FROM Register r
GROUP BY r.contest_id
ORDER BY percentage DESC, r.contest_id ASC;

1211. Queries Quality and Percentage

  • 官方链接:1211
  • 题意概述:按查询名计算质量均值和低评分占比。
  • 常见表:Queries(query_name, result, position, rating)
  • 考点:表达式平均、条件比例。
代码块SQL · 6 行收起展开
SELECT query_name,
       ROUND(AVG(rating / position), 2) AS quality,
       ROUND(AVG(rating < 3) * 100, 2) AS poor_query_percentage
FROM Queries
WHERE query_name IS NOT NULL
GROUP BY query_name;

1193. Monthly Transactions I

  • 官方链接:1193
  • 题意概述:按月份和国家统计交易数、通过数、总金额、通过金额。
  • 常见表:Transactions(id, country, state, amount, trans_date)
  • 考点:DATE_FORMAT、条件聚合。
代码块SQL · 8 行收起展开
SELECT DATE_FORMAT(trans_date, '%Y-%m') AS month,
       country,
       COUNT(*) AS trans_count,
       SUM(state = 'approved') AS approved_count,
       SUM(amount) AS trans_total_amount,
       SUM(IF(state = 'approved', amount, 0)) AS approved_total_amount
FROM Transactions
GROUP BY month, country;

1174. Immediate Food Delivery II

  • 官方链接:1174
  • 题意概述:计算每个客户首单中即时配送订单的百分比。
  • 常见表:Delivery(delivery_id, customer_id, order_date, customer_pref_delivery_date)
  • 考点:先定位每个客户首单,再算比例。
代码块SQL · 7 行收起展开
SELECT ROUND(AVG(order_date = customer_pref_delivery_date) * 100, 2) AS immediate_percentage
FROM Delivery
WHERE (customer_id, order_date) IN (
    SELECT customer_id, MIN(order_date)
    FROM Delivery
    GROUP BY customer_id
);

550. Game Play Analysis IV

  • 官方链接:550
  • 题意概述:计算玩家首次登录次日仍登录的比例。
  • 常见表:Activity(player_id, device_id, event_date, games_played)
  • 考点:首日子查询、次日留存。
代码块SQL · 9 行收起展开
SELECT ROUND(COUNT(a2.player_id) / COUNT(a1.player_id), 2) AS fraction
FROM (
    SELECT player_id, MIN(event_date) AS first_login
    FROM Activity
    GROUP BY player_id
) a1
LEFT JOIN Activity a2
  ON a1.player_id = a2.player_id
 AND DATEDIFF(a2.event_date, a1.first_login) = 1;

Sorting and Grouping

2356. Number of Unique Subjects Taught by Each Teacher

  • 官方链接:2356
  • 题意概述:统计每位教师教授的不同科目数。
  • 常见表:Teacher(teacher_id, subject_id, dept_id)
  • 考点:COUNT(DISTINCT ...)
代码块SQL · 4 行收起展开
SELECT teacher_id,
       COUNT(DISTINCT subject_id) AS cnt
FROM Teacher
GROUP BY teacher_id;

1141. User Activity for the Past 30 Days I

  • 官方链接:1141
  • 题意概述:统计指定日期前 30 天内每天活跃用户数。
  • 常见表:Activity(user_id, session_id, activity_date, activity_type)
  • 考点:日期区间、去重用户。
代码块SQL · 5 行收起展开
SELECT activity_date AS day,
       COUNT(DISTINCT user_id) AS active_users
FROM Activity
WHERE activity_date BETWEEN DATE_SUB('2019-07-27', INTERVAL 29 DAY) AND '2019-07-27'
GROUP BY activity_date;

1070. Product Sales Analysis III

  • 官方链接:1070
  • 题意概述:找出每个商品第一次销售年份对应的销售记录。
  • 常见表:Sales(sale_id, product_id, year, quantity, price)
  • 考点:分组取最小年份,再回表筛选。
代码块SQL · 10 行收起展开
SELECT product_id,
       year AS first_year,
       quantity,
       price
FROM Sales
WHERE (product_id, year) IN (
    SELECT product_id, MIN(year)
    FROM Sales
    GROUP BY product_id
);

596. Classes With at Least 5 Students

  • 官方链接:596
  • 题意概述:找出至少有 5 名学生的课程。
  • 常见表:Courses(student, class)
  • 考点:HAVING
代码块SQL · 4 行收起展开
SELECT class
FROM Courses
GROUP BY class
HAVING COUNT(student) >= 5;

1729. Find Followers Count

  • 官方链接:1729
  • 题意概述:统计每个用户的粉丝数,按用户 id 升序。
  • 常见表:Followers(user_id, follower_id)
  • 考点:分组计数。
代码块SQL · 5 行收起展开
SELECT user_id,
       COUNT(follower_id) AS followers_count
FROM Followers
GROUP BY user_id
ORDER BY user_id;

619. Biggest Single Number

  • 官方链接:619
  • 题意概述:找出只出现一次的最大数字;不存在则返回 NULL
  • 常见表:MyNumbers(num)
  • 考点:先筛唯一值,再 MAX()
代码块SQL · 7 行收起展开
SELECT MAX(num) AS num
FROM (
    SELECT num
    FROM MyNumbers
    GROUP BY num
    HAVING COUNT(*) = 1
) t;

1045. Customers Who Bought All Products

  • 官方链接:1045
  • 题意概述:找出购买过所有商品的客户。
  • 常见表:Customer(customer_id, product_key)Product(product_key)
  • 考点:集合覆盖,购买的不同商品数等于商品总数。
代码块SQL · 7 行收起展开
SELECT customer_id
FROM Customer
GROUP BY customer_id
HAVING COUNT(DISTINCT product_key) = (
    SELECT COUNT(*)
    FROM Product
);

Advanced Select and Joins

1731. The Number of Employees Which Report to Each Employee

  • 官方链接:1731
  • 题意概述:统计每位经理的直属汇报人数和汇报员工平均年龄。
  • 常见表:Employees(employee_id, name, reports_to, age)
  • 考点:自连接、ROUND(AVG())
代码块SQL · 9 行收起展开
SELECT m.employee_id,
       m.name,
       COUNT(e.employee_id) AS reports_count,
       ROUND(AVG(e.age)) AS average_age
FROM Employees m
JOIN Employees e
  ON m.employee_id = e.reports_to
GROUP BY m.employee_id, m.name
ORDER BY m.employee_id;

1789. Primary Department for Each Employee

  • 官方链接:1789
  • 题意概述:找出每个员工的主部门;如果员工只有一个部门,则该部门就是主部门。
  • 常见表:Employee(employee_id, department_id, primary_flag)
  • 考点:主标记或单部门判断。
代码块SQL · 9 行收起展开
SELECT employee_id, department_id
FROM Employee
WHERE primary_flag = 'Y'
   OR employee_id IN (
       SELECT employee_id
       FROM Employee
       GROUP BY employee_id
       HAVING COUNT(*) = 1
   );

610. Triangle Judgement

  • 官方链接:610
  • 题意概述:判断三条边是否可以构成三角形。
  • 常见表:Triangle(x, y, z)
  • 考点:CASE WHEN
代码块SQL · 6 行收起展开
SELECT x, y, z,
       CASE
           WHEN x + y > z AND x + z > y AND y + z > x THEN 'Yes'
           ELSE 'No'
       END AS triangle
FROM Triangle;

180. Consecutive Numbers

  • 官方链接:180
  • 题意概述:找出连续出现至少 3 次的数字。
  • 常见表:Logs(id, num)
  • 考点:连续 id 自连接。
代码块SQL · 8 行收起展开
SELECT DISTINCT l1.num AS ConsecutiveNums
FROM Logs l1
JOIN Logs l2
  ON l2.id = l1.id + 1
JOIN Logs l3
  ON l3.id = l1.id + 2
WHERE l1.num = l2.num
  AND l2.num = l3.num;

1164. Product Price at a Given Date

  • 官方链接:1164
  • 题意概述:查询指定日期每个商品的价格;该日期前没有改价记录则价格为 10。
  • 常见表:Products(product_id, new_price, change_date)
  • 考点:每组取指定日期前最后一条记录,默认值。
代码块SQL · 17 行收起展开
SELECT p.product_id,
       IFNULL(x.new_price, 10) AS price
FROM (
    SELECT DISTINCT product_id
    FROM Products
) p
LEFT JOIN (
    SELECT product_id, new_price
    FROM Products
    WHERE (product_id, change_date) IN (
        SELECT product_id, MAX(change_date)
        FROM Products
        WHERE change_date <= '2019-08-16'
        GROUP BY product_id
    )
) x
  ON p.product_id = x.product_id;

1204. Last Person to Fit in the Bus

  • 官方链接:1204
  • 题意概述:按上车顺序累计重量,找出不超过 1000 的最后一人。
  • 常见表:Queue(person_id, person_name, weight, turn)
  • 考点:窗口函数累计和。
代码块SQL · 9 行收起展开
SELECT person_name
FROM (
    SELECT person_name,
           SUM(weight) OVER (ORDER BY turn) AS total_weight
    FROM Queue
) t
WHERE total_weight <= 1000
ORDER BY total_weight DESC
LIMIT 1;

1907. Count Salary Categories

  • 官方链接:1907
  • 题意概述:按低、中、高三档收入统计账户数,三档都要输出。
  • 常见表:Accounts(account_id, income)
  • 考点:UNION ALL 固定输出类别。
代码块SQL · 18 行收起展开
SELECT 'Low Salary' AS category,
       COUNT(*) AS accounts_count
FROM Accounts
WHERE income < 20000

UNION ALL

SELECT 'Average Salary' AS category,
       COUNT(*) AS accounts_count
FROM Accounts
WHERE income BETWEEN 20000 AND 50000

UNION ALL

SELECT 'High Salary' AS category,
       COUNT(*) AS accounts_count
FROM Accounts
WHERE income > 50000;

Subqueries

1978. Employees Whose Manager Left the Company

  • 官方链接:1978
  • 题意概述:找出工资低于 30000 且经理已离职的员工。
  • 常见表:Employees(employee_id, name, manager_id, salary)
  • 考点:子查询判断经理是否仍存在。
代码块SQL · 8 行收起展开
SELECT employee_id
FROM Employees
WHERE salary < 30000
  AND manager_id NOT IN (
      SELECT employee_id
      FROM Employees
  )
ORDER BY employee_id;

626. Exchange Seats

  • 官方链接:626
  • 题意概述:相邻学生交换座位,最后一个奇数座位不变。
  • 常见表:Seat(id, student)
  • 考点:CASE 生成新 id。
代码块SQL · 8 行收起展开
SELECT CASE
           WHEN id % 2 = 1 AND id = (SELECT MAX(id) FROM Seat) THEN id
           WHEN id % 2 = 1 THEN id + 1
           ELSE id - 1
       END AS id,
       student
FROM Seat
ORDER BY id;

1341. Movie Rating

  • 官方链接:1341
  • 题意概述:返回评分次数最多的用户,以及 2020 年 2 月平均评分最高的电影。
  • 常见表:Movies(movie_id, title)Users(user_id, name)MovieRating(movie_id, user_id, rating, created_at)
  • 考点:两个查询用 UNION ALL 合并,平局按字典序。
代码块SQL · 18 行收起展开
(SELECT u.name AS results
 FROM MovieRating mr
 JOIN Users u
   ON mr.user_id = u.user_id
 GROUP BY mr.user_id, u.name
 ORDER BY COUNT(*) DESC, u.name ASC
 LIMIT 1)

UNION ALL

(SELECT m.title AS results
 FROM MovieRating mr
 JOIN Movies m
   ON mr.movie_id = m.movie_id
 WHERE mr.created_at BETWEEN '2020-02-01' AND '2020-02-29'
 GROUP BY mr.movie_id, m.title
 ORDER BY AVG(mr.rating) DESC, m.title ASC
 LIMIT 1);

1321. Restaurant Growth

  • 官方链接:1321
  • 题意概述:按日期计算最近 7 天的营业额总和及日均金额。
  • 常见表:Customer(customer_id, name, visited_on, amount)
  • 考点:先按天汇总,再做 7 日窗口。
代码块SQL · 25 行收起展开
WITH daily AS (
    SELECT visited_on,
           SUM(amount) AS amount
    FROM Customer
    GROUP BY visited_on
),
rolling AS (
    SELECT visited_on,
           SUM(amount) OVER (
               ORDER BY visited_on
               ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
           ) AS amount,
           ROUND(AVG(amount) OVER (
               ORDER BY visited_on
               ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
           ), 2) AS average_amount
    FROM daily
)
SELECT visited_on, amount, average_amount
FROM rolling
WHERE visited_on >= (
    SELECT DATE_ADD(MIN(visited_on), INTERVAL 6 DAY)
    FROM daily
)
ORDER BY visited_on;

602. Friend Requests II: Who Has the Most Friends

  • 官方链接:602
  • 题意概述:统计 requester 和 accepter 两侧的好友数,找好友最多的人。
  • 常见表:RequestAccepted(requester_id, accepter_id, accept_date)
  • 考点:UNION ALL 拉平成一列后计数。
代码块SQL · 12 行收起展开
SELECT id,
       COUNT(*) AS num
FROM (
    SELECT requester_id AS id
    FROM RequestAccepted
    UNION ALL
    SELECT accepter_id AS id
    FROM RequestAccepted
) t
GROUP BY id
ORDER BY num DESC
LIMIT 1;

585. Investments in 2016

  • 官方链接:585
  • 题意概述:求满足指定条件的 2016 投保额总和:2015 投保额有重复,坐标位置唯一。
  • 常见表:Insurance(pid, tiv_2015, tiv_2016, lat, lon)
  • 考点:两个分组条件同时过滤。
代码块SQL · 14 行收起展开
SELECT ROUND(SUM(tiv_2016), 2) AS tiv_2016
FROM Insurance
WHERE tiv_2015 IN (
    SELECT tiv_2015
    FROM Insurance
    GROUP BY tiv_2015
    HAVING COUNT(*) > 1
)
AND (lat, lon) IN (
    SELECT lat, lon
    FROM Insurance
    GROUP BY lat, lon
    HAVING COUNT(*) = 1
);

185. Department Top Three Salaries

  • 官方链接:185
  • 题意概述:找出每个部门工资排名前三的员工,工资并列算同一名次。
  • 常见表:Employee(id, name, salary, departmentId)Department(id, name)
  • 考点:相关子查询计算有多少个更高的不同工资。
代码块SQL · 12 行收起展开
SELECT d.name AS Department,
       e.name AS Employee,
       e.salary AS Salary
FROM Employee e
JOIN Department d
  ON e.departmentId = d.id
WHERE (
    SELECT COUNT(DISTINCT e2.salary)
    FROM Employee e2
    WHERE e2.departmentId = e.departmentId
      AND e2.salary > e.salary
) < 3;

Advanced String Functions / Regex / Clause

1667. Fix Names in a Table

  • 官方链接:1667
  • 题意概述:把姓名改成首字母大写、其余小写。
  • 常见表:Users(user_id, name)
  • 考点:UPPERLOWERLEFTSUBSTRING
代码块SQL · 4 行收起展开
SELECT user_id,
       CONCAT(UPPER(LEFT(name, 1)), LOWER(SUBSTRING(name, 2))) AS name
FROM Users
ORDER BY user_id;

1527. Patients With a Condition

  • 官方链接:1527
  • 题意概述:找出病症列表中包含以 DIAB1 开头的病症代码的患者。
  • 常见表:Patients(patient_id, patient_name, conditions)
  • 考点:单词边界正则。
代码块SQL · 3 行收起展开
SELECT patient_id, patient_name, conditions
FROM Patients
WHERE conditions REGEXP '(^| )DIAB1';

196. Delete Duplicate Emails

  • 官方链接:196
  • 题意概述:删除重复邮箱,只保留同邮箱最小 id 的记录。
  • 常见表:Person(id, email)
  • 考点:自连接删除。
代码块SQL · 5 行收起展开
DELETE p1
FROM Person p1
JOIN Person p2
  ON p1.email = p2.email
 AND p1.id > p2.id;

176. Second Highest Salary

  • 官方链接:176
  • 题意概述:返回第二高工资,没有则返回 NULL
  • 常见表:Employee(id, salary)
  • 考点:子查询包住 LIMIT,保证无结果时返回一行 NULL
代码块SQL · 6 行收起展开
SELECT (
    SELECT DISTINCT salary
    FROM Employee
    ORDER BY salary DESC
    LIMIT 1 OFFSET 1
) AS SecondHighestSalary;

1484. Group Sold Products By The Date

  • 官方链接:1484
  • 题意概述:按日期统计售出商品种类数,并按字典序拼接商品名。
  • 常见表:Activities(sell_date, product)
  • 考点:GROUP_CONCAT(DISTINCT ... ORDER BY ...)
代码块SQL · 6 行收起展开
SELECT sell_date,
       COUNT(DISTINCT product) AS num_sold,
       GROUP_CONCAT(DISTINCT product ORDER BY product SEPARATOR ',') AS products
FROM Activities
GROUP BY sell_date
ORDER BY sell_date;

1327. List the Products Ordered in a Period

  • 官方链接:1327
  • 题意概述:找出 2020 年 2 月订购量至少 100 的商品。
  • 常见表:Products(product_id, product_name, product_category)Orders(product_id, order_date, unit)
  • 考点:日期过滤后分组求和。
代码块SQL · 8 行收起展开
SELECT p.product_name,
       SUM(o.unit) AS unit
FROM Products p
JOIN Orders o
  ON p.product_id = o.product_id
WHERE o.order_date BETWEEN '2020-02-01' AND '2020-02-29'
GROUP BY p.product_id, p.product_name
HAVING SUM(o.unit) >= 100;

1517. Find Users With Valid E-Mails

  • 官方链接:1517
  • 题意概述:找出合法邮箱用户:用户名以字母开头,只能含字母、数字、下划线、点、短横线,域名为 @leetcode.com
  • 常见表:Users(user_id, name, mail)
  • 考点:正则匹配完整字符串。
代码块SQL · 3 行收起展开
SELECT user_id, name, mail
FROM Users
WHERE mail REGEXP '^[A-Za-z][A-Za-z0-9_.-]*@leetcode[.]com$';

高频模板

1. 保留左表全部记录

代码块SQL · 4 行收起展开
SELECT a.*, b.col
FROM A a
LEFT JOIN B b
  ON a.id = b.id;

2. 找左表有、右表没有

代码块SQL · 5 行收起展开
SELECT a.*
FROM A a
LEFT JOIN B b
  ON a.id = b.id
WHERE b.id IS NULL;

3. 分组后筛选

代码块SQL · 4 行收起展开
SELECT group_col, COUNT(*) AS cnt
FROM T
GROUP BY group_col
HAVING COUNT(*) >= 5;

4. 条件聚合

代码块SQL · 4 行收起展开
SELECT
    SUM(status = 'ok') AS ok_count,
    ROUND(AVG(status = 'ok'), 2) AS ok_rate
FROM T;

5. 每组取第一条

代码块SQL · 7 行收起展开
SELECT *
FROM T
WHERE (group_id, sort_col) IN (
    SELECT group_id, MIN(sort_col)
    FROM T
    GROUP BY group_id
);

6. 累计和

代码块SQL · 3 行收起展开
SELECT id,
       SUM(amount) OVER (ORDER BY id) AS running_amount
FROM T;