Leetcode高頻 SQL 50 題(基礎版)題目記錄

Leetcode sql題目記錄

文章目錄

    • Leetcode sql題目記錄
      • 570. 至少有5名直接下屬的經理
      • 1934. 確認率
      • 1193. 每月交易I
      • 1174. 即時食物配送II
      • 176. 第二高的薪水
        • (1) 子查詢為空但外層用了聚合函數
        • (2)子查詢為空而外層沒有聚合函數
      • 550. 游戲玩法分析IV
      • 1045. 買下所有產品的客戶
      • 180. 連續出現的數字
      • 1164. 指定日期的產品價格
        • (1)非相關子查詢 + 等值比較
        • (2)相關子查詢
        • (3)窗口函數 + 條件篩選
        • (4)ORDER BY + LIMIT
        • 對比總結
      • 1204.最后一個能進入巴士的人
        • (1)子查詢+等值過濾
        • (2)ORDER BY+LIMIT
      • 1907. 按分類統計薪水
      • 626. 換座位
        • (1)嵌套查詢
        • (2)CASE WHEN
          • a. 簡單 CASE
          • b. 搜索 CASE (最常用)
          • c. 作為一個字段輸出
          • d. 在聚合函數里做條件統計
          • e. 排序(ORDER BY)

本博客僅記錄高頻 SQL 50 題(基礎版)的中等難度題目 苯人的解答與學習過程,后續不定期更新

570. 至少有5名直接下屬的經理

表: Employee

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
| department  | varchar |
| managerId   | int     |
+-------------+---------+
id 是此表的主鍵(具有唯一值的列)。
該表的每一行表示雇員的名字、他們的部門和他們的經理的id。
如果managerId為空,則該員工沒有經理。
沒有員工會成為自己的管理者。

編寫一個解決方案,找出至少有五個直接下屬的經理。

任意順序 返回結果表。

查詢結果格式如下所示。

示例 1:

輸入: 
Employee 表:
+-----+-------+------------+-----------+
| id  | name  | department | managerId |
+-----+-------+------------+-----------+
| 101 | John  | A          | Null      |
| 102 | Dan   | A          | 101       |
| 103 | James | A          | 101       |
| 104 | Amy   | A          | 101       |
| 105 | Anne  | A          | 101       |
| 106 | Ron   | B          | 101       |
+-----+-------+------------+-----------+
輸出: 
+------+
| name |
+------+
| John |
+------+

解答:

select a.name from Employee a join Employee b on a.id = b.managerId group by a.id having count(*) >= 5;

沒有 GROUP BY
HAVING 是對分組后的結果過濾的。你沒分組時,MySQL把整張結果集當成一個大組COUNT(a.id) 統計的是所有經理–下屬配對的總行數,不是“每個經理的下屬數”。因此當測試數據里只有一個經理且剛好有 5 個下屬時看起來“正確”,但只要有兩個經理,合計行數 ≥5,你這句就會把兩位經理都放進結果里,甚至還會重復多行。


1934. 確認率

表: Signups

+----------------+----------+
| Column Name    | Type     |
+----------------+----------+
| user_id        | int      |
| time_stamp     | datetime |
+----------------+----------+
User_id是該表的主鍵。
每一行都包含ID為user_id的用戶的注冊時間信息。

表: Confirmations

+----------------+----------+
| Column Name    | Type     |
+----------------+----------+
| user_id        | int      |
| time_stamp     | datetime |
| action         | ENUM     |
+----------------+----------+
(user_id, time_stamp)是該表的主鍵。
user_id是一個引用到注冊表的外鍵。
action是類型為('confirmed', 'timeout')的ENUM
該表的每一行都表示ID為user_id的用戶在time_stamp請求了一條確認消息,該確認消息要么被確認('confirmed'),要么被過期('timeout')。

用戶的 確認率'confirmed' 消息的數量除以請求的確認消息的總數。沒有請求任何確認消息的用戶的確認率為 0 。確認率四舍五入到 小數點后兩位

編寫一個SQL查詢來查找每個用戶的 確認率 。

以 任意順序 返回結果表。

查詢結果格式如下所示。

示例1:

輸入:
Signups 表:
+---------+---------------------+
| user_id | time_stamp          |
+---------+---------------------+
| 3       | 2020-03-21 10:16:13 |
| 7       | 2020-01-04 13:57:59 |
| 2       | 2020-07-29 23:09:44 |
| 6       | 2020-12-09 10:39:37 |
+---------+---------------------+
Confirmations 表:
+---------+---------------------+-----------+
| user_id | time_stamp          | action    |
+---------+---------------------+-----------+
| 3       | 2021-01-06 03:30:46 | timeout   |
| 3       | 2021-07-14 14:00:00 | timeout   |
| 7       | 2021-06-12 11:57:29 | confirmed |
| 7       | 2021-06-13 12:58:28 | confirmed |
| 7       | 2021-06-14 13:59:27 | confirmed |
| 2       | 2021-01-22 00:00:00 | confirmed |
| 2       | 2021-02-28 23:59:59 | timeout   |
+---------+---------------------+-----------+
輸出: 
+---------+-------------------+
| user_id | confirmation_rate |
+---------+-------------------+
| 6       | 0.00              |
| 3       | 0.00              |
| 7       | 1.00              |
| 2       | 0.50              |
+---------+-------------------+
解釋:
用戶 6 沒有請求任何確認消息。確認率為 0。
用戶 3 進行了 2 次請求,都超時了。確認率為 0。
用戶 7 提出了 3 個請求,所有請求都得到了確認。確認率為 1。
用戶 2 做了 2 個請求,其中一個被確認,另一個超時。確認率為 1 / 2 = 0.5。

解答:

WITH base AS (SELECT user_id,COUNT(*) AS total,SUM(CASE WHEN action = 'confirmed' THEN 1 ELSE 0 END) AS confirmedFROM ConfirmationsGROUP BY user_id
)
SELECT s.user_id,ROUND(IFNULL(b.confirmed / b.total, 0), 2) AS confirmation_rate
FROM Signups s
LEFT JOIN base bON s.user_id = b.user_id;

1193. 每月交易I

表:Transactions

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| country       | varchar |
| state         | enum    |
| amount        | int     |
| trans_date    | date    |
+---------------+---------+
id 是這個表的主鍵。
該表包含有關傳入事務的信息。
state 列類型為 ["approved", "declined"] 之一。

編寫一個 sql 查詢來查找每個月和每個國家/地區的事務數及其總金額、已批準的事務數及其總金額。

任意順序 返回結果表。

查詢結果格式如下所示。

示例 1:

輸入:
Transactions table:
+------+---------+----------+--------+------------+
| id   | country | state    | amount | trans_date |
+------+---------+----------+--------+------------+
| 121  | US      | approved | 1000   | 2018-12-18 |
| 122  | US      | declined | 2000   | 2018-12-19 |
| 123  | US      | approved | 2000   | 2019-01-01 |
| 124  | DE      | approved | 2000   | 2019-01-07 |
+------+---------+----------+--------+------------+
輸出:
+----------+---------+-------------+----------------+--------------------+-----------------------+
| month    | country | trans_count | approved_count | trans_total_amount | approved_total_amount |
+----------+---------+-------------+----------------+--------------------+-----------------------+
| 2018-12  | US      | 2           | 1              | 3000               | 1000                  |
| 2019-01  | US      | 1           | 1              | 2000               | 2000                  |
| 2019-01  | DE      | 1           | 1              | 2000               | 2000                  |
+----------+---------+-------------+----------------+--------------------+-----------------------+

解答:

多個 CTE 用 WITH a AS (...), b AS (...)

month、country 分組;approved 相關用 CASE WHEN 計數/求和。

取月份用 DATE_FORMAT(trans_date, '%Y-%m') 更穩妥。

WITH base AS (SELECTDATE_FORMAT(trans_date, '%Y-%m') AS month,country,state,amountFROM Transactions
),
seq AS (SELECTmonth,country,COUNT(*) AS trans_count,SUM(CASE WHEN state = 'approved' THEN 1 ELSE 0 END) AS approved_count,SUM(amount) AS trans_total_amount,SUM(CASE WHEN state = 'approved' THEN amount ELSE 0 END) AS approved_total_amountFROM baseGROUP BY month, country
)
SELECT *
FROM seq;

1174. 即時食物配送II

配送表: Delivery

+-----------------------------+---------+
| Column Name                 | Type    |
+-----------------------------+---------+
| delivery_id                 | int     |
| customer_id                 | int     |
| order_date                  | date    |
| customer_pref_delivery_date | date    |
+-----------------------------+---------+
delivery_id 是該表中具有唯一值的列。
該表保存著顧客的食物配送信息,顧客在某個日期下了訂單,并指定了一個期望的配送日期(和下單日期相同或者在那之后)。

如果顧客期望的配送日期和下單日期相同,則該訂單稱為 「即時訂單」,否則稱為「計劃訂單」。

首次訂單」是顧客最早創建的訂單。我們保證一個顧客只會有一個「首次訂單」。

編寫解決方案以獲取即時訂單在所有用戶的首次訂單中的比例。保留兩位小數。

結果示例如下所示:

示例 1:

輸入:
Delivery 表:
+-------------+-------------+------------+-----------------------------+
| delivery_id | customer_id | order_date | customer_pref_delivery_date |
+-------------+-------------+------------+-----------------------------+
| 1           | 1           | 2019-08-01 | 2019-08-02                  |
| 2           | 2           | 2019-08-02 | 2019-08-02                  |
| 3           | 1           | 2019-08-11 | 2019-08-12                  |
| 4           | 3           | 2019-08-24 | 2019-08-24                  |
| 5           | 3           | 2019-08-21 | 2019-08-22                  |
| 6           | 2           | 2019-08-11 | 2019-08-13                  |
| 7           | 4           | 2019-08-09 | 2019-08-09                  |
+-------------+-------------+------------+-----------------------------+
輸出:
+----------------------+
| immediate_percentage |
+----------------------+
| 50.00                |
+----------------------+
解釋:
1 號顧客的 1 號訂單是首次訂單,并且是計劃訂單。
2 號顧客的 2 號訂單是首次訂單,并且是即時訂單。
3 號顧客的 5 號訂單是首次訂單,并且是計劃訂單。
4 號顧客的 7 號訂單是首次訂單,并且是即時訂單。
因此,一半顧客的首次訂單是即時的。

解答:

with base as (
select *, row_number() over(partition by customer_id order by order_date) as rn 
from Delivery),
seq as (select round((sum(case when customer_pref_delivery_date = order_date then 1 else 0 end) / count(*)) * 100, 2) as immediate_percentage from base where rn = 1
)
select * from seq;

176. 第二高的薪水

Employee 表:

+-------------+------+
| Column Name | Type |
+-------------+------+
| id          | int  |
| salary      | int  |
+-------------+------+
id 是這個表的主鍵。
表的每一行包含員工的工資信息。

查詢并返回 Employee 表中第二高的 不同 薪水 。如果不存在第二高的薪水,查詢應該返回 null(Pandas 則返回 None)

查詢結果如下例所示。

示例 1:

輸入:
Employee 表:
+----+--------+
| id | salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+
輸出:
+---------------------+
| SecondHighestSalary |
+---------------------+
| 200                 |
+---------------------+

示例 2:

輸入:
Employee 表:
+----+--------+
| id | salary |
+----+--------+
| 1  | 100    |
+----+--------+
輸出:
+---------------------+
| SecondHighestSalary |
+---------------------+
| null                |
+---------------------+

解答

SELECT MAX(salary) AS SecondHighestSalary
FROM (SELECT DISTINCT salary,DENSE_RANK() OVER (ORDER BY salary DESC) AS rkFROM Employee
) t
WHERE rk = 2;
(1) 子查詢為空但外層用了聚合函數

SQL 的定義是:聚合函數對空輸入時,返回 NULL
例子:

SELECT MAX(salary) FROM (SELECT 1 AS salary WHERE 1=0) t;

(SELECT 1 WHERE 1=0) 為空表 → MAX 沒有任何值可比較 → 返回 NULL

所以這就是為什么“第二高薪水不存在”時 MAX 可以幫我們自動返回 NULL


(2)子查詢為空而外層沒有聚合函數

如果你直接:

SELECT salary 
FROM (SELECT salary WHERE 1=0) t;

那結果就是 0 行(即直接返回空結果集,不會自動給你一行 NULL)。


550. 游戲玩法分析IV

Table: Activity

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| player_id    | int     |
| device_id    | int     |
| event_date   | date    |
| games_played | int     |
+--------------+---------+
(player_id,event_date)是此表的主鍵(具有唯一值的列的組合)。
這張表顯示了某些游戲的玩家的活動情況。
每一行是一個玩家的記錄,他在某一天使用某個設備注銷之前登錄并玩了很多游戲(可能是 0)。

編寫解決方案,報告在首次登錄的第二天再次登錄的玩家的 比率四舍五入到小數點后兩位。換句話說,你需要計算從首次登錄后的第二天登錄的玩家數量,并將其除以總玩家數。

結果格式如下所示:

示例 1:

輸入:
Activity table:
+-----------+-----------+------------+--------------+
| player_id | device_id | event_date | games_played |
+-----------+-----------+------------+--------------+
| 1         | 2         | 2016-03-01 | 5            |
| 1         | 2         | 2016-03-02 | 6            |
| 2         | 3         | 2017-06-25 | 1            |
| 3         | 1         | 2016-03-02 | 0            |
| 3         | 4         | 2018-07-03 | 5            |
+-----------+-----------+------------+--------------+
輸出:
+-----------+
| fraction  |
+-----------+
| 0.33      |
+-----------+
解釋:
只有 ID 為 1 的玩家在第一天登錄后才重新登錄,所以答案是 1/3 = 0.33

解答:

# Write your MySQL query statement below
with base as(select *,min(event_date) over(partition by player_id)as first from Activity
),
seq as(select player_id, sum(case when datediff(event_date, first) = 1 then 1 else 0 end) as rn from basegroup by player_id
)
select round(IFNULL((sum(rn) / count(distinct player_id)), 0), 2) as fraction from seq;

注意:

  1. 在使用with base as(), seq as() select from seq時,要記得每個嵌套內部的select很重要,前一個select需要包含后一個select的內容。
  2. 使用聚合函數min,max,count后結果會被壓縮,如果后續要同行對最大、最小進行比較,要使用窗口函數形式的max,min…

1045. 買下所有產品的客戶

Customer 表:

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| customer_id | int     |
| product_key | int     |
+-------------+---------+
該表可能包含重復的行。
customer_id 不為 NULL。
product_key 是 Product 表的外鍵(reference 列)。

Product 表:

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| product_key | int     |
+-------------+---------+
product_key 是這張表的主鍵(具有唯一值的列)。

編寫解決方案,報告 Customer 表中購買了 Product 表中所有產品的客戶的 id。

返回結果表 無順序要求

返回結果格式如下所示。

示例 1:

輸入:
Customer 表:
+-------------+-------------+
| customer_id | product_key |
+-------------+-------------+
| 1           | 5           |
| 2           | 6           |
| 3           | 5           |
| 3           | 6           |
| 1           | 6           |
+-------------+-------------+
Product 表:
+-------------+
| product_key |
+-------------+
| 5           |
| 6           |
+-------------+
輸出:
+-------------+
| customer_id |
+-------------+
| 1           |
| 3           |
+-------------+
解釋:
購買了所有產品(5 和 6)的客戶的 id 是 1 和 3 。

解答:

  1. WHERE DISTINCT 是非法語法DISTINCT 只能放在 SELECTCOUNT(DISTINCT ...) 里面,不能直接放在 WHERE
  2. 題目要求的是“買了所有產品的顧客”,所以應該比較顧客買到的 去重后產品數Product 表里的產品總數
SELECT customer_id
FROM Customer
GROUP BY customer_id
HAVING COUNT(DISTINCT product_key) = (SELECT COUNT(*) FROM Product
);

解釋一下:

  • GROUP BY customer_id:按顧客分組。
  • COUNT(DISTINCT product_key):統計該顧客買了多少種不同的產品。
  • 子查詢 (SELECT COUNT(*) FROM Product):統計總共有多少種產品。
  • HAVING ... = ...:篩選出買全所有產品的顧客。

180. 連續出現的數字

表:Logs

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| num         | varchar |
+-------------+---------+
在 SQL 中,id 是該表的主鍵。
id 是一個自增列。

找出所有至少連續出現三次的數字。

返回的結果表中的數據可以按 任意順序 排列。

結果格式如下面的例子所示:

示例 1:

輸入:
Logs 表:
+----+-----+
| id | num |
+----+-----+
| 1  | 1   |
| 2  | 1   |
| 3  | 1   |
| 4  | 2   |
| 5  | 1   |
| 6  | 2   |
| 7  | 2   |
+----+-----+
輸出:
Result 表:
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1               |
+-----------------+
解釋:1 是唯一連續出現至少三次的數字。

解答:

with base as(select *, row_number() over(partition by num order by id) as rn from Logs
),
seq as(select *, id - rn as diff from base 
),
rpq as (select num, count(*) as ct from seq group by num, diff having count(*) >= 3
)
select distinct num as ConsecutiveNums from rpq;

有時候不要忘記distinct


1164. 指定日期的產品價格

產品數據表: Products

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| product_id    | int     |
| new_price     | int     |
| change_date   | date    |
+---------------+---------+
(product_id, change_date) 是此表的主鍵(具有唯一值的列組合)。
這張表的每一行分別記錄了 某產品 在某個日期 更改后 的新價格。

一開始,所有產品價格都為 10。

編寫一個解決方案,找出在 2019-08-16 所有產品的價格。

任意順序 返回結果表。

結果格式如下例所示。

示例 1:

輸入:
Products 表:
+------------+-----------+-------------+
| product_id | new_price | change_date |
+------------+-----------+-------------+
| 1          | 20        | 2019-08-14  |
| 2          | 50        | 2019-08-14  |
| 1          | 30        | 2019-08-15  |
| 1          | 35        | 2019-08-16  |
| 2          | 65        | 2019-08-17  |
| 3          | 20        | 2019-08-18  |
+------------+-----------+-------------+
輸出:
+------------+-------+
| product_id | price |
+------------+-------+
| 2          | 50    |
| 1          | 35    |
| 3          | 10    |
+------------+-------+

解答:

with base as(select *, row_number()over (partition by product_id order by change_date DESC) as rn from Products where change_date <= '2019-08-16'
),
seq as (select product_id, new_price as price from base where rn = 1
)
select product_id, price from seq union all select distinct product_id, 10 as price from (select product_id, min(change_date) as mi from Products group by product_id
)t  where mi > '2019-08-16';

歸納:
想要得到某一列的最大最小值,并用其與某個數進行比較,需要先max、min(窗口或者聚合函數),然后再等值查詢,或者rownumber配合ASC、DESC,然后再后續查詢中使用rn=1,或者直接使用order by+limit

(1)非相關子查詢 + 等值比較

使用場景全局只有一個最值(整個表的最大值/最小值),不依賴分組。

  • 特點:子查詢返回單行,可以直接用 = 比較。
  • 示例:找出工資最高的員工
select *
from Employee
where salary = (select max(salary) from Employee);

(2)相關子查詢

使用場景分組后的最值(每個客戶/部門的最小/最大日期),外層表的條件依賴子查詢。

  • 特點:子查詢里需要引用外層的列,每行執行一次,保證返回單行。
  • 示例:找每個客戶的首單
select *
from Delivery d1
where order_date = (select min(order_date)from Delivery d2where d2.customer_id = d1.customer_id
);

這里子查詢里的 d2.customer_id = d1.customer_id 綁定了外層查詢的 d1.customer_id

每次外層取一行,子查詢就只計算該客戶的最小訂單日期。

也可以寫成這種形式:

select *
from (select customer_id, min(order_date)from Delivery group by customer_id
)t ;

(3)窗口函數 + 條件篩選

使用場景:數據庫支持窗口函數(MySQL 8+ / PostgreSQL / Oracle / SQL Server),需要按組取前幾名/最值。

也可以使用max、min的窗口函數形式來獲取每個組別的最值

  • 特點:寫法簡潔,可同時保留分組內排序信息。
  • 示例:找每個客戶的首單
with t as (select *,row_number() over(partition by customer_id order by order_date) as rnfrom Delivery
)
select *
from t
where rn = 1;
  • 如果要處理并列情況,可以用 rank()dense_rank()

(4)ORDER BY + LIMIT

使用場景只需要全表范圍內的最值,且只取前 N 條(不分組)。

  • 特點:簡單高效,但無法直接應對「每組最值」問題。
  • 示例:找工資最高的員工(Top 1)
select *
from Employee
order by salary desc
limit 1;
  • 如果需要每組最值,就不適合,只能配合窗口函數或子查詢。

對比總結
方法適用場景優點局限
非相關子查詢全表唯一最值簡單只能處理單個全局最值
相關子查詢每組最值(需要依賴外層條件)通用,不要求窗口函數子查詢多次執行,性能較差
窗口函數每組最值/前 N 個高效簡潔,現代 SQL 推薦需要數據庫支持窗口函數
ORDER BY + LIMIT全表前 N 個簡潔高效不能分組,只能處理全局最值

👉 快速記憶:

  • 全局最值 → 非相關子查詢 或 order by + limit
  • 分組最值 → 相關子查詢 或 窗口函數
  • 要前 N 名/并列情況 → 窗口函數最佳

1204.最后一個能進入巴士的人

表: Queue

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| person_id   | int     |
| person_name | varchar |
| weight      | int     |
| turn        | int     |
+-------------+---------+
person_id 是這個表具有唯一值的列。
該表展示了所有候車乘客的信息。
表中 person_id 和 turn 列將包含從 1 到 n 的所有數字,其中 n 是表中的行數。
turn 決定了候車乘客上巴士的順序,其中 turn=1 表示第一個上巴士,turn=n 表示最后一個上巴士。
weight 表示候車乘客的體重,以千克為單位。

有一隊乘客在等著上巴士。然而,巴士有1000 千克 的重量限制,所以其中一部分乘客可能無法上巴士。

編寫解決方案找出 最后一個 上巴士且不超過重量限制的乘客,并報告 person_name 。題目測試用例確保順位第一的人可以上巴士且不會超重。

返回結果格式如下所示。

示例 1:

輸入:
Queue 表
+-----------+-------------+--------+------+
| person_id | person_name | weight | turn |
+-----------+-------------+--------+------+
| 5         | Alice       | 250    | 1    |
| 4         | Bob         | 175    | 5    |
| 3         | Alex        | 350    | 2    |
| 6         | John Cena   | 400    | 3    |
| 1         | Winston     | 500    | 6    |
| 2         | Marie       | 200    | 4    |
+-----------+-------------+--------+------+
輸出:
+-------------+
| person_name |
+-------------+
| John Cena   |
+-------------+
解釋:
為了簡化,Queue 表按 turn 列由小到大排序。
+------+----+-----------+--------+--------------+
| Turn | ID | Name      | Weight | Total Weight |
+------+----+-----------+--------+--------------+
| 1    | 5  | Alice     | 250    | 250          |
| 2    | 3  | Alex      | 350    | 600          |
| 3    | 6  | John Cena | 400    | 1000         | (最后一個上巴士)
| 4    | 2  | Marie     | 200    | 1200         | (無法上巴士)
| 5    | 4  | Bob       | 175    | ___          |
| 6    | 1  | Winston   | 500    | ___          |
+------+----+-----------+--------+--------------+

解答:

PS:SQL 聚合函數(如 MAX())和普通列之間沒有自動的“行對齊”關系。

不能直接寫成!:

select person_name, max(total_weight) from (select * , sum(weight)over (order by turn) as total_weight from Queue
)t where total_weight <= 1000;-- 結果只會返回
| person_id | person_name | weight | turn |
| --------- | ----------- | ------ | ---- |
| 5         | Alice       | 250    | 1    |
| 4         | Bob         | 175    | 5    |
| 3         | Alex        | 350    | 2    |
| 6         | John Cena   | 400    | 3    |
| 1         | Winston     | 500    | 6    |
| 2         | Marie       | 200    | 4    || person_name | max(total_weight) |
| ----------- | ----------------- |
| Alice       | 1000              |-- 而不是正確輸出
| person_name |
| ----------- |
| John Cena   |
(1)子查詢+等值過濾
# Write your MySQL query statement below
with base as(select * , sum(weight)over (order by turn) as total_weight from Queue
)
select person_name from base where total_weight = (select max(total_weight) as mx from base where total_weight <= 1000
);

(2)ORDER BY+LIMIT
# Write your MySQL query statement below
select person_name from (select * , sum(weight)over (order by turn) as total_weight from Queue
)t where total_weight <= 1000 order by total_weight DESC limit 1;

1907. 按分類統計薪水

表: Accounts

+-------------+------+
| 列名        | 類型  |
+-------------+------+
| account_id  | int  |
| income      | int  |
+-------------+------+
在 SQL 中,account_id 是這個表的主鍵。
每一行都包含一個銀行帳戶的月收入的信息。

查詢每個工資類別的銀行賬戶數量。 工資類別如下:

  • "Low Salary":所有工資 嚴格低于 20000 美元。
  • "Average Salary"包含 范圍內的所有工資 [$20000, $50000]
  • "High Salary":所有工資 嚴格大于 50000 美元。

結果表 必須 包含所有三個類別。 如果某個類別中沒有帳戶,則報告 0

任意順序 返回結果表。

查詢結果格式如下示例。

示例 1:

輸入:
Accounts 表:
+------------+--------+
| account_id | income |
+------------+--------+
| 3          | 108939 |
| 2          | 12747  |
| 8          | 87709  |
| 6          | 91796  |
+------------+--------+
輸出:
+----------------+----------------+
| category       | accounts_count |
+----------------+----------------+
| Low Salary     | 1              |
| Average Salary | 0              |
| High Salary    | 3              |
+----------------+----------------+
解釋:
低薪: 有一個賬戶 2.
中等薪水: 沒有.
高薪: 有三個賬戶,他們是 3, 6和 8.

解答:

select 'Low Salary' as category, sum(case when income < 20000 then 1 else 0 end) as accounts_count
from Accounts
Union all
select 'Average Salary' as category, sum(case when income >= 20000 and income <= 50000 then 1 else 0 end) as accounts_count
from Accounts
Union all
select 'High Salary' as category, sum(case when income > 50000 then 1 else 0 end) as accounts_count
from Accounts;

626. 換座位

表: Seat

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| student     | varchar |
+-------------+---------+
id 是該表的主鍵(唯一值)列。
該表的每一行都表示學生的姓名和 ID。
ID 序列始終從 1 開始并連續增加。

編寫解決方案來交換每兩個連續的學生的座位號。如果學生的數量是奇數,則最后一個學生的id不交換。

id 升序 返回結果表。

查詢結果格式如下所示。

示例 1:

輸入: 
Seat 表:
+----+---------+
| id | student |
+----+---------+
| 1  | Abbot   |
| 2  | Doris   |
| 3  | Emerson |
| 4  | Green   |
| 5  | Jeames  |
+----+---------+
輸出: 
+----+---------+
| id | student |
+----+---------+
| 1  | Doris   |
| 2  | Abbot   |
| 3  | Green   |
| 4  | Emerson |
| 5  | Jeames  |
+----+---------+
解釋:
請注意,如果學生人數為奇數,則不需要更換最后一名學生的座位。

解答:

(1)嵌套查詢
# Write your MySQL query statement below
with base as(select *, lead(student, 1)over (order by id) as exchange_nxt, lag(student, 1)over (order by id) as exchange_pre from Seat
)
select id, IFNULL((case when (id % 2) != 0 then exchange_nxt else exchange_pre end), student) as student from base;
(2)CASE WHEN
# Write your MySQL query statement below
select case when id % 2 = 1 and id < (select max(id) from Seat)then id + 1when id % 2 = 0 then id - 1else idend as id, studentfrom Seat
order by id;

在 SQL 里,CASE 可以寫兩種形式:

a. 簡單 CASE

直接對某個表達式的值做匹配:

CASE column_nameWHEN 'A' THEN '類型1'WHEN 'B' THEN '類型2'ELSE '其他'
END
b. 搜索 CASE (最常用)

條件判斷靈活,可以寫比較、范圍等:

CASEWHEN score >= 90 THEN '優秀'WHEN score >= 60 THEN '及格'ELSE '不及格'
END
c. 作為一個字段輸出
SELECT name,CASE WHEN age < 18 THEN '未成年'WHEN age < 60 THEN '成年人'ELSE '老年人'END AS age_group
FROM users;
d. 在聚合函數里做條件統計
SELECTSUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS success_count,SUM(CASE WHEN status = 'fail' THEN 1 ELSE 0 END)    AS fail_count
FROM logs;

常用于 條件計數

e. 排序(ORDER BY)
SELECT *
FROM orders
ORDER BYCASE WHEN status = 'vip' THEN 1WHEN status = 'normal' THEN 2ELSE 3END;

補充:

SQL執行順序:

  • FROM Employee
  • WHERE salary > 5000 (先篩掉工資不夠的行)
  • GROUP BY dept (按部門分組)
  • COUNT(*) 統計每組人數
  • HAVING 過濾出人數 ≥3 的部門
  • SELECT 輸出 dept, cnt
  • ORDER BY 按 cnt 降序
  • LIMIT 取前 5 個部門

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921201.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921201.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921201.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RAGFlow切分方法詳解

RAGFlow 各切分方法的含義如下,結合文檔結構、場景特點等設計,以適配不同類型的知識源: 1. General(通用分塊) 邏輯:結合文本排版、格式、語義關聯等因素確定分割點,再根據“建議文本塊大小(Token 數)”,將文本切分為合適的塊。 支持格式:DOCX、EXCEL、PPT、IMAGE、…

支付域——支付與交易概念

摘要本文詳細闡述了支付域中支付與交易的核心概念及其相互關系。交易是商品或服務交換的過程&#xff0c;包含多個要素并產生訂單或合同。支付則是資金流轉的過程&#xff0c;是交易的資金結算環節。支付交易結合了兩者&#xff0c;根據不同場景提供多樣化的支付產品和服務。文…

(自用)cmd常用命令自查文檔

&#xff08;自用&#xff09;cmd常用命令自查文檔 Windows CMD 常用命令自查1. 文件與目錄操作命令說明示例?cd?顯示或切換目錄?cd?&#xff1b;cd C:\Windows??dir?列出目錄內容?dir?&#xff1b;dir /a?(含隱藏文件)?md?或mkdir?創建目錄?md test?&#xff1…

劇本殺APP系統開發:引領娛樂行業新潮流的科技力量

在當今數字化時代&#xff0c;科技的力量正深刻地改變著人們的生活方式和娛樂習慣。娛樂行業也不例外&#xff0c;各種新興的娛樂形式和平臺如雨后春筍般涌現。劇本殺APP系統開發作為科技與娛樂融合的產物&#xff0c;正以其獨特的魅力和創新的模式&#xff0c;引領著娛樂行業的…

LangChain框架深度解析:定位、架構、設計邏輯與優化方向

LangChain框架深度解析&#xff1a;定位、架構、設計邏輯與優化方向 引言 在大語言模型&#xff08;LLM&#xff09;應用開發的浪潮中&#xff0c;LangChain作為最具影響力的開發框架之一&#xff0c;為開發者提供了構建復雜AI應用的完整工具鏈。本文將從框架定位、實現邏輯、設…

面試常備與開發必知:一文掌握MySQL字符串拼接的所有核心技巧

? 在 MySQL 中拼接字符串是一個非常常見的操作&#xff0c;主要用于查詢時動態組合多個字段或值。以下是幾種最核心和常用的方法。一、核心拼接函數1. CONCAT(str1, str2, ...)這是最通用、最常用的字符串拼接函數。它接受兩個或多個字符串參數&#xff0c;并將它們按順…

數據可視化大屏精選開源項目

為您精心挑選和整理了一系列在 GitHub 上廣受好評的數據可視化大屏開源項目。這些項目覆蓋了不同的技術棧&#xff08;Vue、React、ECharts、D3.js等&#xff09;&#xff0c;適合從初學者到資深開發者不同層次的需求。 我將它們分為以下幾類&#xff0c;方便您選擇&#xff1…

LeetCode 3516.找到最近的人:計算絕對值大小

【LetMeFly】3516.找到最近的人&#xff1a;計算絕對值大小 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/find-closest-person/ 給你三個整數 x、y 和 z&#xff0c;表示數軸上三個人的位置&#xff1a; x 是第 1 個人的位置。y 是第 2 個人的位置。z 是第 3 個人…

【面試】MySQL 面試常見優化問題

1. 為什么要建索引&#xff1f;索引一定能提高性能嗎&#xff1f;場景&#xff1a;一個表有上千萬數據&#xff0c;查詢 SELECT * FROM user WHERE age25;。問題&#xff1a;沒有索引時會全表掃描&#xff0c;性能差。解決方案&#xff1a;給 age 建立普通索引&#xff0c;加快…

Access開發導出PDF的N種姿勢,你get了嗎?

目錄 基礎篇&#xff1a;一行代碼搞定 實戰篇&#xff1a;讓導出更智能 進階篇&#xff1a;用戶體驗升級 總結 hi&#xff0c;大家好呀&#xff01; 今天我們來聊聊一個非常實用的功能——如何用VBA將Access中的數據導出為PDF。 相信很多朋友在日常工作中都遇到過這樣的需…

JavaAI炫技賽:電商系統商品管理模塊的創新設計與實踐探索

一、引言電商行業的競爭日益激烈&#xff0c;電商系統商品管理模塊的高效性、智能化程度成為企業提升競爭力的關鍵因素。Java 作為企業級開發的主流語言&#xff0c;憑借其穩定性和強大的生態系統&#xff0c;在電商系統開發中占據重要地位。而 AI 技術的融入&#xff0c;為商品…

關于如何在PostgreSQL中調整數據庫參數和配置的綜合指南

關于如何在PostgreSQL中調整數據庫參數和配置的綜合指南 PostgreSQL是一個非常通用的數據庫系統,能夠在低資源環境和與各種其他應用程序共享的環境中高效運行。為了確保它將在許多不同的環境中正常運行,默認配置非常保守,不太適合高性能生產數據庫。加上地理空間數據庫具有…

wps的excel如何轉為谷歌在線表格

1.?打開 Google Sheets&#xff08;sheets.google.com&#xff09;。 2.?新建一個空白表格。3.?點擊菜單 文件 → 導入 (File → Import)。4.?選擇在 WPS 保存好的 .xlsx 文件上傳。5.?選擇 “新建表格” 或 “替換當前表格”&#xff0c;就能直接在 Google Sheets 使用注…

貓頭虎AI 薦研|騰訊開源長篇敘事音頻生成模型 AudioStory:統一模型,讓 AI 會講故事

&#x1f42f;貓頭虎薦研&#xff5c;騰訊開源長篇敘事音頻生成模型 AudioStory&#xff1a;統一模型&#xff0c;讓 AI 會講故事 大家好&#xff0c;我是貓頭虎 &#x1f42f;&#x1f989;&#xff0c;又來給大家推薦新鮮出爐的 AI 開源項目&#xff01; 這次要聊的是騰訊 A…

收藏!VSCode 開發者工具快捷鍵大全

一、文件操作快捷鍵1. 打開與關閉文件Ctrl O&#xff08;Windows/Linux&#xff09;或 Command O&#xff08;Mac&#xff09;&#xff1a;打開文件&#xff0c;可以通過輸入文件名快速查找并打開相應文件。Ctrl W&#xff08;Windows/Linux&#xff09;或 Command W&#…

Simulations RL 平臺學習筆記

1. 選擇標準 1.1 開源項目&#xff0c;&#x1f31f;star數量越多越好 2. 常見平臺 2.1 &#x1f31f;18.6k ML-Agents&#xff1a;基于Unity實現 2.2 &#x1f31f;1.2k Godot RL Agents

【國內電子數據取證廠商龍信科技】IOS 逆向脫殼

我們都知道&#xff0c;大多數的 APP 在開發的時候一般都會加上一層殼&#xff0c;例如 愛加密、梆梆、360、網易易盾等等。那 APK 的脫殼我們見得多了&#xff0c;那 IOS 逆向脫殼又是怎樣子的呢&#xff1f;首先咱們先了解一下為什么要砸殼&#xff0c;因為 IOS 開發者開發軟…

基于STM32單片機溫濕度PM2.5粉塵甲醛環境質量wifi手機APP監測系統

1 基于STM32單片機溫濕度PM2.5粉塵甲醛環境質量WiFi手機APP監測系統 本系統旨在實現對環境中溫度、濕度、PM2.5粉塵濃度以及甲醛濃度的實時監測&#xff0c;并通過WiFi技術將數據傳輸至手機APP端&#xff0c;實現移動化與可視化的環境質量檢測。系統在硬件上主要依賴STM32單片…

用C++實現日期類

在上學的時候&#xff0c;總是在計算還有多少天放假&#xff1b;在上班的時候&#xff0c;總是在計算還有多久發工資&#xff1f;我們一般通過日歷得到結果&#xff0c;那自己能不能實現一些基本的功能呢&#xff1f;答案是可以的&#xff01;需要實現內容&#xff1a;1. 日期加…

百度網盤基于Flink的實時計算實踐

01 概覽 隨著數字化轉型的來臨&#xff0c;企業對于數據服務的實時化需求日益增長&#xff0c;在大規模數據和復雜場景的情況下&#xff0c;Flink在實時計算數據鏈路中扮演著極為重要的角色&#xff0c;本文介紹了網盤如何通過 Flink 構建實時計算引擎&#xff0c;從而提供高性…