[面試分享] SQL 面試準備攻略:準備技巧、刷題資源與範例解析

更新 發佈閱讀 25 分鐘
本文基於作者 20+ 場新創及全球科技公司的面試經驗,以及擔任面試官的實戰經驗,深度解析 SQL 技術面試的評估標準與準備策略,並提供 5 道經典題目解析,助你順利通過技術關卡!

SQL 面試會考些什麼?

(1) 基礎 SQL 能力

(1) 正確且具備邏輯的把 SQL 寫出來 (2) 能善用 where 或其他方法有效優化 SQL (3) 易讀性的 Format 以及註解

範例題目

raw-image

評分標準

  • 正確且具備邏輯的把 SQL 寫出來
    • 先求有再求好!我作為面試官的經驗來說,Junior 的 SQL 面試有 85% 在測驗語法。產品經驗可以入職後累積,但如果連基礎能力都沒有,主管還需要花時間指導 SQL,這類候選人高機率會被刷掉。
    • 當題目變得複雜無法用一段 query 寫完的時候,請善用 CTE 或是 Subquery 進行拆解。我個人是 CTE 派因為閱讀性較高,面試官可以很好的從頭到尾理解資料處理的邏輯。
    • 另外,我會盡量以設計 pipeline 的角度,而不是一次性 ad-hoc query 去作答。這樣的好處是以後遇到不同的需求或是題目,你都可以用同一套邏輯去解決。
      -- Ad-hoc 版本
      WITH may AS (
      SELECT user_id
      FROM orders
      WHERE DATE_TRUNC(date, MONTH) = "2025-05-01"
      ),
      june AS (
      SELECT user_id
      FROM orders
      WHERE DATE_TRUNC(date, MONTH) = "2025-06-01"
      )
      SELECT
      COUNT(DISTINCT june.user_id) / COUNT(DISTINCT may.user_id) AS retention_rate
      FROM may
      LEFT JOIN june
      ON may.user_id = june.user_id
      	-- pipeline 設計理念版本
      WITH retention AS (
      SELECT
      DATE_TRUNC(o1.date, MONTH) AS purchase_month,
      COUNT(DISTINCT o1.user_id) AS users
      COUNT(DISTINCT o2.user_id) AS reorder_users
      FROM orders AS o1
      LEFT JOIN orders AS o2
      ON o1.user_id = o2.user_id
      AND DATE_TRUNC(o1.date, MONTH) = DATE_SUB(DATE_TRUNC(o2.date, MONTH), INTERVAL 1 MONTH)
      WHERE DATE_TRUNC(o1.date, MONTH) = "2025-05-01"
      )
      SELECT
      purchase_month,
      reorder_users / users AS retention_rate
      FROM retention
      -- WHERE purchase_month = "2025-05-01"
  • 能善用 where 或其他方法有效優化 SQL
    • 我個人認為優化是最常被忽略的一環,即便在日常作業中,很多人也不太在意優化,最後可能導致 pipeline timeout 以及浪費運算資源產生的超額帳單。
    • 最直觀的優化就是減少不必要的資料獲取。範例題當中,我們已經知道兩個條件 (1) 日期 (2) 訂閱用戶,我們可以對兩張 table 都進行資料篩選,減少 join 所需要的資料量。
  • 易讀性的 Format 以及註解
    • 註解的部分看你是線上考或是機考,線上考我會先闡述想法後再開始作答,比較少有註解。機考則是儘量都有註解,特別是需要多個 CTE 的題目,我會把每個 CTE 的目的寫清楚,方便面試官改考卷。
    • Format 部分很看面試官個人偏好,但我個人非常注重。你可以有自己風格,但請貫徹到底。不要看這個好像很小、很沒意義,未來會大大影響到 PR review 以及 debug 的速度。
  • -- 無格式化版本
    SELECT date,
    platform,count(distinct user_id) users
    FROM table
    WHERE (platform = "android"
    and date = "2025-05-01")or (
    platform = "ios" AND (
    date = "2025-05-03" and is_subscribed))or(
    platform = "web"
    and date = "2025-05-02")
    group by date,
    platform
    order by date
    ASC
    -- 格式化版本
    SELECT
    date,
    platform,
    COUNT(DISTINCT user_id) AS users
    FROM table
    WHERE
    (
    platform = "android"
    AND date = "2025-05-01"
    ) OR (
    platform = "ios"
    AND (
    date = "2025-05-03"
    AND is_subscribed
    )
    ) OR (
    platform = "web"
    AND date = "2025-05-02"
    )
    GROUP BY date, platform
    ORDER BY date

如何準備 - 刷題

為什麼需要刷題?

  • 即便你是身經百戰的分析師,我還是強烈建議要刷題,量可以少但不能沒有。刷題的用意是模擬面試環境,並提前熟悉各種不同的題型,一旦面試出現跟你日常工作毫無相關的資料或是陌生的指標,很容易就慌了手腳。
  • 以上述範例來說,日常工作中我們會 GROUP BY 日期做計算,然後把結果丟進 Excel 或是 BI tool 製圖,這樣做會導致你拿不到 2025/05/02 的資料,但多半不影響視覺化的結果。如果你沒有事先碰過這類題目,面試當下你可能就愣住了,不曉得怎麼在結果中列出所有日期的資料。
  • 另外,刷題的過程中可以接觸到不同產業以及公司的考古題,而 SQL 考試中的問題,同時也就是指標,很有可能會跟應徵職位的日常工作息息相關,等於同時也準備後續的 Product 技術關。

去哪刷?怎麼刷?

  • 我以前刷題都在 LeetCode 進行,但我覺得題目品質不太好,過於簡單,和真實考題的難度脫鉤,再加上有些題目很刻意在考語法。後來轉戰使用 Stratascratch 覺得還不錯,上面可以篩選公司找考古題,除了 SQL 以外也有統計和 product case 等相關的問題可以練習。文章最後也會放一些題目解析。
  • 我自己是會把 Hard 刷完一輪,如果還有時間才會刷 Medium 維持手感,Easy 過於簡單我完全不碰。頻率的部分,我大概每天刷 1 - 3 題,取決於多快可以把 Hard 刷乾。
  • 除了正確解答以外,刷題的速度也重要。在準備 Meta 面試的時候,我是會限定自己要在 10 分鐘以內寫完 Hard,然後完成優化,藉此模擬面試當下的壓力測試。

(2) Product Mindset

當面對不熟悉的產品以及數據下,在有限的時間內有條有理的闡述自己的想法,最終透過 SQL 實現,就是這類型題目的核心

範例題目

raw-image

評分標準

  • 這類題目多半出現在 Senior 的面試中,更多的是了解你對於產品的理解程度,以及在面對不熟悉的產品時如何拆解問題,並來回與面試官溝通。

如何準備

  • 以上述範例來說,你會需要定義何謂 Top,DAU、總時長或是總使用次數都可以是指標。此時,你要先提出假設並根據假設進行解答。舉例來說:
    • 不同類別的 app 有不同的 Top 定義,假設這類 app 都是社群媒體相關的,我們應該以 DAU 作為主要指標,因為 social media 最主要的目標是不斷地吸引用戶持續使用。
    • 然而,如果是遊戲類型的居多,duration 可能就會變得更為重要。
  • 我個人覺得這部分不用在 SQL 階段特別準備。我會這樣說是因為在準備 product case 的時候同時就已經在思考這些問題了。舉例來說:「我們發現流量在某天暴增然後隔天又暴跌,你會怎麼解讀該數據?」,這類題目中已經包含處理資料以及解析數據的能力。

常見 SQL Function

General Function

  • 最基本的語法: select, from, where
  • Aggregate Function: sum, count, count distinct, avg, …
  • union 與 union all 的差異: 前者去重複,後者不會

Window Function

  • Ranking (rank, dense_rank, row_number)
raw-image
  • lag vs lead
  • precentile (這個我很少遇到,而且不是每個類型的 SQL 都通用)
raw-image

Date Function

raw-image

SQL 刷題解析

[Medium] Election Results

重點

  • 三種可能
    • 投廢票 (空白字串)
    • 投一個候選人
    • 投多個候選人
  • 每個人的 votes 只看到小數點第三位
  • 有可能有多個第一名

解題邏輯

  • 計算每個 voter 總共投了幾個候選人,並且均分票數
  • 加總後排序,並取得第一名

答案

WITH voter_data AS (
SELECT
voter,
1.0 / COUNT(DISTINCT candidate) AS votes
FROM voting_results
WHERE candidate IS NOT NULL AND candidate != ''
GROUP BY voter
),
final_result AS (
SELECT
vr.candidate,
SUM(ROUND(votes, 3)) AS votes -- 這裡最好問清楚 ROUND 是針對最後票數,還是針對每個人
FROM voting_results AS vr
INNER JOIN voter_data AS vd
ON vr.voter = vd.voter
WHERE vr.candidate IS NOT NULL AND vr.candidate != ''
GROUP BY vr.candidate
),
ranking AS (
SELECT
*,
RANK() OVER(ORDER BY votes DESC) AS final_rank
FROM final_result
)
SELECT candidate
FROM ranking
WHERE final_rank = 1

[Medium] Premium Accounts

重點

  • 只需要最早的七個日期答案 → Limit 7 or row_number() ≤ 7
  • actively paying 的定義是 final_price 不等於 0
  • reactively paying 的定義只看七天後,不管中間

解題邏輯

  • 針對 account id 和 date 進行 self join
  • 分別計算有多少 actively paying 和 reactively paying
  • sort 日期後取前七筆資料

答案

SELECT
p1.entry_date,
COUNT(DISTINCT CASE WHEN p1.final_price != 0 THEN p1.account_id END) AS premium_paid_accounts,
COUNT(DISTINCT CASE WHEN p1.final_price != 0 AND p2.final_price != 0 THEN p1.account_id END) AS premium_paid_accounts_after_7d
FROM premium_accounts_by_day AS p1
LEFT JOIN premium_accounts_by_day AS p2
ON p1.account_id = p2.account_id
AND DATEDIFF(p2.entry_date, p1.entry_date) = 7
GROUP BY p1.entry_date
ORDER BY p1.entry_date
LIMIT 7

[Hard] Marketing Campaign Success [Advanced]

重點

  • Campaign 影響定義
    • Campaign 只會在首購日後開始作用 → 首購日
    • 購買首購日相同商品將不會被歸因 → 首購日中的所有商品
  • 題目沒有特別標明 Campaign 是否持續進行,以及其歸因範圍,如果面試中有遇到類似問題,建議和面試官確認邏輯。 ex: campaign 只會持續七天

解題邏輯

  • 取得首購日以及首購日中所有商品
    • 我是把兩個邏輯切開來計算,先拿到首購日,進行 join 取得首購商品
    • 精簡優化的話,可以在第一個 CTE 用 window function 計算首購日後,最終 join 的時候篩選首購日中的商品
  • 確認首購日後購買的商品是否不同,當至少一個商品不同時,歸因給 campaign

答案

-- First Purchase Date
-- First Purchase Item ID

-- first purchase date products
WITH fdo AS (
SELECT
user_id,
product_id,
DATE(created_at) AS purchase_date,
FIRST_VALUE(DATE(created_at)) OVER (PARTITION BY user_id ORDER BY created_at) AS first_purchase_date
FROM marketing_campaign
),
retention AS (
SELECT
mc.user_id,
mc.product_id,
MAX(CASE WHEN mc.product_id = fdo.product_id THEN 1 ELSE 0 END) AS has_purchased
FROM marketing_campaign AS mc
INNER JOIN (
SELECT
user_id,
product_id,
first_purchase_date
FROM fdo
WHERE purchase_date = first_purchase_date
) AS fdo
ON mc.user_id = fdo.user_id
AND DATE(mc.created_at) > fdo.first_purchase_date #DATE_ADD(ftb.first_purchase_date, INTERVAL 1 DAY)
GROUP BY mc.user_id, mc.product_id
)
SELECT COUNT(DISTINCT user_id) AS users
FROM retention
WHERE has_purchased = 0

[Hard] Retention Rate

重點

  • account_id 為單位計算 retention rate
  • retention rate 的定義是該月後有回訪即算,不論多晚回訪
  • 要計算 Jan 2021 retention rate / Dec 2020 retention rate,例外處理為 0

解題邏輯

  • 討論區有解答是直接計算資料庫中每個 account 最後的互動月份,再以此計算 retention rate,雖然這樣也沒錯,但如果今天把 retention 的定義改為僅考慮下一個月,這種做法就不可行。因此,我會用設計 pipeline 的寫法,而不是針對題目客製的答案。
  • self join 去取得該月後所有的資料
    • 如果需要更改 retention 的定義,在第一個 join 的 condition 做調整即可
  • 分別計算 2020 Dec 和 2021 Jan 的 retention rate
  • 相除後做例外處理取得最終答案

答案

WITH retention_raw AS (
SELECT
DATE_FORMAT(e1.record_date, '%Y-%m') AS record_month,
e1.user_id,
e1.account_id,
MAX(CASE WHEN e2.record_date IS NOT NULL THEN 1 ELSE 0 END) AS has_retention
FROM sf_events AS e1
LEFT JOIN sf_events AS e2
ON DATE_FORMAT(e1.record_date, '%Y-%m') < DATE_FORMAT(e2.record_date, '%Y-%m')
AND e1.user_id = e2.user_id
AND e1.account_id = e2.account_id
GROUP BY DATE_FORMAT(e1.record_date, '%Y-%m'), e1.user_id, e1.account_id
),
dec_retention AS (
SELECT
account_id,
COUNT(DISTINCT CASE WHEN has_retention = 1 THEN user_id END) / COUNT(DISTINCT user_id) AS retention_rate
FROM retention_raw
WHERE record_month = "2020-12"
GROUP BY account_id
),
jan_retention AS (
SELECT
account_id,
COUNT(DISTINCT CASE WHEN has_retention = 1 THEN user_id END) / COUNT(DISTINCT user_id) AS retention_rate
FROM retention_raw
WHERE record_month = "2021-01"
GROUP BY account_id
)
SELECT
j.account_id,
IFNULL(j.retention_rate / d.retention_rate, 0) AS retention
FROM jan_retention AS j
LEFT JOIN dec_retention AS d
ON d.account_id = j.account_id

[Hard] Most Popular Client For Calls

重點

  • most popular client,有可能會有多個值,最好和考官確認期待 output
  • popular 的定義是 number of users
  • users 需要進行篩選,他們產生的 event 資料中要有至少 50% 是 call 相關的 event

解題邏輯

  • 根據條件篩選合格 user
  • group by client 計算合格 user 數量
  • 依照 user 數量排序,取得最熱門的 client
    • 如果僅需一個結果,可以用 row_number,不過要再三確認其排序邏輯
    • 如果有多個同樣熱門的 client 且需要把所有結果都列出來,用 rank 或 dense_rank 才會是正確答案

答案

-- most popular client_id, 1 or multiple output?
-- video events >= 50% of total events

WITH events_agg AS (
SELECT
client_id,
user_id,
1.0 * COUNT(DISTINCT
CASE
WHEN event_type IN (
'video call received',
'video call sent',
'voice call received',
'voice call sent'
) THEN id
END
) / COUNT(DISTINCT id) AS call_events_share
FROM fact_events
GROUP BY client_id, user_id
),
client_user_cnt AS (
SELECT
client_id,
COUNT(DISTINCT user_id) AS users
FROM events_agg
WHERE call_events_share >= 0.5
),
client_sort AS (
SELECT
client_id,
RANK() OVER(PARTITION BY client_id ORDER BY users DESC) AS client_rank
FROM client_user_cnt
)
SELECT client_id
FROM client_sort
WHERE client_rank = 1
留言
avatar-img
分析遊蹤
14會員
56內容數
多元化的文章內容,主題包括數據分析分享、旅遊心得和個人投資心得。我們提供有價值的內容,幫助讀者探索數據世界、計劃下一次旅行和做出明智的財務決策。
分析遊蹤的其他內容
2024/08/03
Tiktok 面試內容因面試官而異。遇到的面試官問題都很 hard core,針對技術問題有非常細部的討論。建議想面試 Tiktok 的人給自己多點時間面試,除了深以外也要顧及廣度
Thumbnail
2024/08/03
Tiktok 面試內容因面試官而異。遇到的面試官問題都很 hard core,針對技術問題有非常細部的討論。建議想面試 Tiktok 的人給自己多點時間面試,除了深以外也要顧及廣度
Thumbnail
2024/06/18
Dcard 是我在 2021 年所有面試公司中體驗最糟糕的,面試官基本上就是有幾年經驗的分析師,技術水平也不是非常卓越,對答中面試官始終採取上對下的高姿態,一臉傲氣且不耐煩地回應你對於問題的疑惑。後續和其他友人閒聊才知道,大家都對於 Dcard 的面試嗤之以鼻。
Thumbnail
2024/06/18
Dcard 是我在 2021 年所有面試公司中體驗最糟糕的,面試官基本上就是有幾年經驗的分析師,技術水平也不是非常卓越,對答中面試官始終採取上對下的高姿態,一臉傲氣且不耐煩地回應你對於問題的疑惑。後續和其他友人閒聊才知道,大家都對於 Dcard 的面試嗤之以鼻。
Thumbnail
2024/06/15
Appier 面試體驗滿好的,對談過程中很順暢且快速,大約兩週多就結束所有面試進入最後薪資談判。值得注意的是該崗位並沒有標示出職等,面試官會根據面試內容去給予其職等,能力達標會直接掛 Senior level。薪資方面應該是台灣數據分析產業數一數二高的,有興趣的人可以試試
Thumbnail
2024/06/15
Appier 面試體驗滿好的,對談過程中很順暢且快速,大約兩週多就結束所有面試進入最後薪資談判。值得注意的是該崗位並沒有標示出職等,面試官會根據面試內容去給予其職等,能力達標會直接掛 Senior level。薪資方面應該是台灣數據分析產業數一數二高的,有興趣的人可以試試
Thumbnail
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
網路上琳琅滿目的面試準備技巧,其中不乏許多常見的表達架構,但是在面試的現場,臨陣磨槍的背誦架構,幫助大嗎? 面試的本質在於雙方了解、面試官的職責在於判斷你與公司以及職務的合適程度,因此在保持禮貌和尊重的前提下,對於自身現況盡量坦誠以告、真實反應吧!
Thumbnail
網路上琳琅滿目的面試準備技巧,其中不乏許多常見的表達架構,但是在面試的現場,臨陣磨槍的背誦架構,幫助大嗎? 面試的本質在於雙方了解、面試官的職責在於判斷你與公司以及職務的合適程度,因此在保持禮貌和尊重的前提下,對於自身現況盡量坦誠以告、真實反應吧!
Thumbnail
這篇文章分享了面試中常詢問的後續流程和時間相關問題,包括詢問後續面試關卡和流程、預計通知下一關面試時間等問題。建議在面試中詢問這些問題,以便掌握招募後續流程和時間,並展現對職缺的熱忱。
Thumbnail
這篇文章分享了面試中常詢問的後續流程和時間相關問題,包括詢問後續面試關卡和流程、預計通知下一關面試時間等問題。建議在面試中詢問這些問題,以便掌握招募後續流程和時間,並展現對職缺的熱忱。
Thumbnail
這篇文章分享了作者對銀行考試的準備和麵試的心得,包含了考試和面試的準備建議以及根據不同銀行的個人想法。如果你正準備銀行考試,這篇文章會給你一些有用的思路。
Thumbnail
這篇文章分享了作者對銀行考試的準備和麵試的心得,包含了考試和面試的準備建議以及根據不同銀行的個人想法。如果你正準備銀行考試,這篇文章會給你一些有用的思路。
Thumbnail
畢業季來臨,對於社會新鮮人來說,面試是展現自己專業能力和個人魅力的重要機會。小編為大家整理了一些在英文面試中常用的句型和....
Thumbnail
畢業季來臨,對於社會新鮮人來說,面試是展現自己專業能力和個人魅力的重要機會。小編為大家整理了一些在英文面試中常用的句型和....
Thumbnail
Professional Cloud Database Engineer 考試/資源/心得整理 |Google Cloud
Thumbnail
Professional Cloud Database Engineer 考試/資源/心得整理 |Google Cloud
Thumbnail
🐳本文收錄於 1111人力銀行 面試經驗談;每週五分鐘,掌握實務技巧,讓你從容應對職場事務!
Thumbnail
🐳本文收錄於 1111人力銀行 面試經驗談;每週五分鐘,掌握實務技巧,讓你從容應對職場事務!
Thumbnail
整理高中考大學各學群常見面試問題,學生可做為參考練習
Thumbnail
整理高中考大學各學群常見面試問題,學生可做為參考練習
Thumbnail
求職一定會遇到的一個關卡,就是「面試」。對於新鮮人或很長時間沒有經歷面試的求職者來說,常常聽到「面試」就覺得皮皮挫!但其實只要做好充足準備,事先掌握面試的流程和內容,就像是考試前就得到了考題一樣,只要好好準備,一定就能獲得期望的成果!
Thumbnail
求職一定會遇到的一個關卡,就是「面試」。對於新鮮人或很長時間沒有經歷面試的求職者來說,常常聽到「面試」就覺得皮皮挫!但其實只要做好充足準備,事先掌握面試的流程和內容,就像是考試前就得到了考題一樣,只要好好準備,一定就能獲得期望的成果!
Thumbnail
這篇寫給天性焦慮想在考試之前搞懂考場detail的夥伴們,準備方法與書單請左轉其他大神的文章><
Thumbnail
這篇寫給天性焦慮想在考試之前搞懂考場detail的夥伴們,準備方法與書單請左轉其他大神的文章><
Thumbnail
網路上的備考與面試經驗分享很多,大部分在於如何準備備審資料、調整心態、以及筆試用書與科目的準備。我在人資領域擔任面試官的角色將近八年,想從比較不一樣的策略角度來分享:當時間與精力有限時,考生可以如何更有策略的準備應考?如何站在學校的立場看自己?用什麼心態準備與呈現,來達到最大被錄取的機會?
Thumbnail
網路上的備考與面試經驗分享很多,大部分在於如何準備備審資料、調整心態、以及筆試用書與科目的準備。我在人資領域擔任面試官的角色將近八年,想從比較不一樣的策略角度來分享:當時間與精力有限時,考生可以如何更有策略的準備應考?如何站在學校的立場看自己?用什麼心態準備與呈現,來達到最大被錄取的機會?
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News