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

SQL 基本查詢

·2 分鐘· ·
演算法 Database Sql
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

介紹
#

LeetCode 的 Database 題用 MySQL。入門題大多是 SELECT 加上 WHERE 過濾,真正容易錯的是 NULL。

模板一:過濾
#

SELECT product_id
FROM Products
WHERE low_fats = 'Y' AND recyclable = 'Y';
  • 字串用單引號 'Y';MySQL 預設也接受雙引號,但 SQL 標準裡雙引號是欄位名稱。
  • 兩個條件都要成立(LC 1757):上面的查詢。

模板二:NULL 的三值邏輯
#

SQL 的條件有三種結果:true、false、unknown。任何跟 NULL 的比較(=、!=、<…)結果都是 unknown,而 WHERE 只留下 true 的列:

SELECT name
FROM Customer
WHERE referee_id IS NULL OR referee_id != 2;

只寫 referee_id != 2 會漏掉 referee_id 是 NULL 的人,因為 NULL != 2 是 unknown,不是 true。

  • 推薦人不是 2 的客戶(LC 584):上面的查詢。也可以寫成 COALESCE(referee_id, 0) != 2。

模板三:JOIN
#

SELECT a.col, b.col
FROM A a
LEFT JOIN B b ON a.key = b.key        -- 左表全部保留,對不到的補 NULL
WHERE b.key IS NULL;                  -- 加上這行:在 B 裡找不到的列
  • 保留沒有對應的列(LC 175):LEFT JOIN;INNER JOIN 會把它們丟掉。
  • 找不存在的列(LC 183):LEFT JOIN ... WHERE b.key IS NULL,或 NOT EXISTS;NOT IN 遇到 NULL 會一筆都不回傳。
  • 同一張表扮演兩個角色(LC 181、197):self join,例如員工接主管(e.managerId = m.id)、今天接前一天(DATEDIFF(w.recordDate, y.recordDate) = 1)。前一天要用日期判斷,不要用 id。

模板四:GROUP BY 和 HAVING
#

SELECT key
FROM T
GROUP BY key
HAVING COUNT(DISTINCT x) >= k;        -- 對分組下條件
  • 出現超過一次(LC 182)、至少 5 個不同的學生(LC 596):WHERE 在分組前過濾單一列,聚合條件要放 HAVING。
  • 刪除重複(LC 196):要真的 DELETE;保留每組的 MIN(id),MySQL 的子查詢要多包一層衍生表才能讀同一張表。

主要參數說明
#

  • IS NULL / IS NOT NULL 才能判斷 NULL。
  • AND 的優先順序比 OR 高,混用時加括號。

複雜度
#

這兩題都是掃一次資料表,O(n)。

常見錯誤
#

  • 用 = NULL 或只用 != 判斷,漏掉 NULL 的列。
  • 字串沒加引號:boring 會被當成欄位名稱(LC 620)。
  • 由高到低忘了 DESC(LC 620)。
  • 欄位沒寫屬於哪個別名:self join 時 Name 有歧義;輸出欄位名稱要照題目(LC 181)。
  • 聚合條件寫在 WHERE、沒用 DISTINCT 計數(LC 596)。
  • 題目要刪除卻寫了 SELECT(LC 196)。
  • 「至少」用了 >(LC 595)。

相關 LeetCode
#

  • LC 1757 Recyclable and Low Fat Products
  • LC 584 Find Customer Referee
  • LC 595 Big Countries
  • LC 620 Not Boring Movies
  • LC 175 Combine Two Tables
  • LC 181 Employees Earning More Than Their Managers
  • LC 183 Customers Who Never Order
  • LC 182 Duplicate Emails
  • LC 596 Classes With at Least 5 Students
  • LC 196 Delete Duplicate Emails
  • LC 197 Rising Temperature

相關文章

LeetCode 1757: Recyclable and Low Fat Products
·1 分鐘
LeetCode Easy Database Sql
LeetCode 1757 解題筆記:兩個條件都要成立,用 WHERE … AND … 過濾
LeetCode 584: Find Customer Referee
·1 分鐘
LeetCode Easy Database Sql
LeetCode 584 解題筆記:referee_id != 2 會漏掉 NULL,因為跟 NULL 比較的結果是 unknown;要另外加上 IS NULL
Array 陣列掃描
·3 分鐘
演算法 Array Simulation Enumeration
相鄰比較與走過單調段(上坡、下坡、山峰與山谷)、一次掃描維護前綴 / 後綴的最大值與總和、小範圍枚舉配對,以及用 tuple 當 key 處理平手
Bit Manipulation 位元運算
·3 分鐘
演算法 Bit-Manipulation
常用的位元操作、AND 只會減少位元而 OR 只會增加位元、用 n & (n » 1) 找相鄰的 1,以及全部是 1 的數 2^k - 1
Bucket Sort 桶子與鴿籠原理
·1 分鐘
演算法 Bucket-Sort Pigeonhole-Principle Sorting
把值域切成 n - 1 個桶子,最大間距一定不會落在同一個桶子裡,所以每個桶子只要記最小值和最大值,就能線性時間找出排序後的最大相鄰差
Hash Table 雜湊表
·4 分鐘
演算法 Hash-Table Counting Array
計數與「次數的次數」、把陣列本身當雜湊表(負號標記)、多個 key 同時計數(列、欄、對角線)、固定左端點增量計數,以及用正規化後的 key 分組