萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 按時間區間分組統計會員數:CASE WHEN 與時間戳轉換兩種方案對比

需求場景

在 tb_user_online_log 表中,依據 create_time(Unix 時間戳)按小時區間統計不重複會員數(COUNT(DISTINCT user_id))。

方案一:CASE WHEN 硬編碼區間(不推薦大數據量)

SELECT
    COUNT(DISTINCT user_id) AS user_count,
    CASE
        WHEN create_time > 1395046800 AND create_time < 1395050400 THEN '17:00-18:00'
        WHEN create_time > 1395050400 AND create_time < 1395054000 THEN '18:00-19:00'
        WHEN create_time > 1395054000 AND create_time < 1395057600 THEN '19:00-20:00'
        WHEN create_time > 1395057600 AND create_time < 1395061200 THEN '20:00-21:00'
        ELSE 'unknown'
    END AS `date`
FROM tb_user_online_log
WHERE create_time > 1395046800 AND create_time < 1395061200
GROUP BY `date`
ORDER BY create_time;

缺點:硬編碼時間戳、區間固定、CASE WHEN 效率低、難以維護擴展。

方案二:FROM_UNIXTIME 動態轉換分組(推薦)

SELECT
    COUNT(DISTINCT user_id) AS user_count,
    FROM_UNIXTIME(create_time, '%Y-%m-%d %H:00:00') AS hours,
    CONCAT(FROM_UNIXTIME(create_time, '%Y-%m-%d %H:00'), '-', FROM_UNIXTIME(create_time, '%H') + 1, ':00') AS `date`
FROM tb_user_online_log
GROUP BY hours
ORDER BY create_time;

優點:

  • 利用內建函數動態生成區間標籤,無需硬編碼。
  • GROUP BY hours 可直接利用索引(若 create_time 有索引)。
  • 靈活支援任意時間範圍、任意粒度(小時、天、月)。

進階技巧:任意粒度分組模板

-- 按天分組
GROUP BY DATE(FROM_UNIXTIME(create_time))

-- 按月分組
GROUP BY DATE_FORMAT(FROM_UNIXTIME(create_time), '%Y-%m')

-- 按 15 分鐘分組
GROUP BY FROM_UNIXTIME(create_time, '%Y-%m-%d %H:%i:00')

效能建議

  • 在 create_time 建立索引。
  • 大表優先用方案二,避免 CASE WHEN 全表掃描且無法用索引。
  • 若頻繁查詢固定區間,可考慮建立物化視覺或摘要表預聚合。
copyright © 萬盛學電腦網 all rights reserved