↓快轉到主要內容
  1. LeetCode/

LeetCode 196: Delete Duplicate Emails

·1 分鐘· ·
LeetCode Easy Database
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: easy 第一次嘗試:2021-10-09

  • 提交紀錄:Wrong Answer ×2 → Accepted

解題思路
#

題目要求修改資料表,所以是 DELETE。要刪的是「同一個 email 裡 id 不是最小的列」。兩種寫法:

  • NOT IN 子查詢:保留每組的 MIN(id),其他刪掉(SQL 模板四)。MySQL 不允許 DELETE 的子查詢直接讀同一張表,所以多包一層衍生表。
  • MySQL 的 self join:DELETE p1 FROM Person p1 JOIN Person p2 ON p1.email = p2.email AND p1.id > p2.id(SQL 模板三)。

我的嘗試
#

前兩版都是 SELECT:先是 SELECT DISTINCT(Email),再來是用 self join 選出要刪的列,但題目要的是真的刪掉,SELECT 不會改資料表。把同一個條件改成 DELETE p1 FROM ... 就 AC 了。

正確解法
#

DELETE FROM Person
WHERE id NOT IN (
    SELECT id FROM (SELECT MIN(id) AS id FROM Person GROUP BY email) AS keep
);

複雜度
#

分組 O(n) 或 O(n log n),再刪除。

要特別避免的錯誤
#

  • 題目要刪除資料,SELECT 不會改到表。
  • MySQL 的 DELETE 子查詢不能直接用同一張表,要多包一層。

面試口說整理
#

題目要直接改資料表,所以我用 DELETE,每個 email 只保留最小的 id:子查詢按 email 分組取最小的 id,其他 id 都刪掉。MySQL 不允許子查詢直接讀要刪的表,所以多包一層衍生表;也可以用 self join 刪掉 id 比較大的那一筆。

相關文章

LeetCode 175: Combine Two Tables
·1 分鐘
LeetCode Easy Database
LeetCode 175 解題筆記:沒有地址的人也要出現,所以用 LEFT JOIN,對不到的 city、state 會是 NULL
LeetCode 181: Employees Earning More Than Their Managers
·1 分鐘
LeetCode Easy Database
LeetCode 181 解題筆記:Employee 跟自己 self join,用 managerId = id 把員工和主管接起來,再比較薪水
LeetCode 182: Duplicate Emails
·1 分鐘
LeetCode Easy Database
LeetCode 182 解題筆記:按 email 分組,HAVING COUNT(*) > 1 留下出現超過一次的
LeetCode 183: Customers Who Never Order
·1 分鐘
LeetCode Easy Database
LeetCode 183 解題筆記:LEFT JOIN Orders,對不到訂單(o.id IS NULL)的就是從來沒下過單的客戶;也可以用 NOT IN
LeetCode 26: Remove Duplicates from Sorted Array
·1 分鐘
LeetCode Easy Array Two-Pointers
LeetCode 26 解題筆記:快慢指針原地覆寫,慢指針指向下一個要寫的位置;遇到跟前一個寫入的值不同才寫
LeetCode 14: Longest Common Prefix
·1 分鐘
LeetCode Easy Array String Trie
LeetCode 14 解題筆記:用最短的字串當上限,逐個位置檢查所有字串是否相同,第一個不同的位置就是答案的長度