最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL實現優(yōu)雅統計工作日(周一至周五)數據

 更新時間:2026年05月13日 09:21:19   作者:身如柳絮隨風揚  
在實際業(yè)務中,我們常常需要統計工作日(周一至周五) 的訪問量、訂單量或用戶活躍度,而剔除周末數據,本文將從基礎方法到高級優(yōu)化,系統講解如何高效統計工作日數據,并提供生產級建議,有需要的可以了解下

在實際業(yè)務中,我們常常需要統計工作日(周一至周五) 的訪問量、訂單量或用戶活躍度,而剔除周末數據。MySQL 提供了多種日期函數來實現這一需求,但不同方案在可讀性、性能、索引利用上差異顯著。本文將從基礎方法到高級優(yōu)化,系統講解如何高效統計工作日數據,并提供生產級建議。

一、業(yè)務場景與挑戰(zhàn)

假設有一張訪問記錄表 visits

CREATE TABLE visits (
    id INT PRIMARY KEY AUTO_INCREMENT,
    visit_date DATETIME NOT NULL,   -- 訪問時間
    user_id INT,
    page VARCHAR(100)
);

需求:統計每天(或某時間段內)工作日的人次,且要求查詢高效、支持大數據量。

挑戰(zhàn):

  • visit_dateDATETIME 類型,包含時分秒。
  • 直接對日期字段使用 WEEKDAY() 等函數會導致索引失效。
  • 數據量百萬級以上時,全表掃描不可接受。

二、基礎查詢方法對比

MySQL 提供多個函數用于判斷星期幾,各有特點:

函數返回值范圍周一對應值周日對應值特點
WEEKDAY(date)0 ~ 606以周一為起點,適合“周一到周五”判斷(<=4)
DAYOFWEEK(date)1 ~ 721以周日為起點,判斷工作日需 BETWEEN 2 AND 6
DAYNAME(date)字符串 (‘Monday’…)‘Monday’‘Sunday’可讀性好,但分組/過濾時需字符串比較
DATE_FORMAT(date, '%w')0 ~ 6(周日=0)10兼容性一般,周日為0需注意

推薦使用 WEEKDAY(),因為其返回值直接對應“周一=0,周五=4”,條件 <=4 語義清晰。

方法1:使用 WEEKDAY() 函數

SELECT 
    DATE(visit_date) AS visit_day,
    COUNT(*) AS visit_count
FROM visits
WHERE WEEKDAY(visit_date) <= 4   -- 0~4 周一到周五
GROUP BY DATE(visit_date)
ORDER BY visit_day;

優(yōu)點:簡單直觀。

缺點WEEKDAY(visit_date) 無法使用 visit_date 上的普通索引。

方法2:使用 DAYOFWEEK() 函數

SELECT 
    DATE(visit_date) AS visit_day,
    COUNT(*) AS visit_count
FROM visits
WHERE DAYOFWEEK(visit_date) BETWEEN 2 AND 6   -- 2=周一,6=周五
GROUP BY DATE(visit_date);

兩者性能相近,但 WEEKDAY 更貼近中國人“周一為一周第一天”的習慣。

方法3:增加星期名稱列(可讀性優(yōu)先)

SELECT 
    DATE(visit_date) AS visit_day,
    CASE WEEKDAY(visit_date)
        WHEN 0 THEN '周一'
        WHEN 1 THEN '周二'
        WHEN 2 THEN '周三'
        WHEN 3 THEN '周四'
        WHEN 4 THEN '周五'
        ELSE '周末'
    END AS weekday_cn,
    COUNT(*) AS visit_count
FROM visits
WHERE WEEKDAY(visit_date) <= 4
GROUP BY DATE(visit_date);

三、性能優(yōu)化方案

當數據量達到百萬級且查詢頻繁時,必須解決 函數導致索引失效 的問題。以下按優(yōu)化程度遞增給出三種方案。

3.1 方案一:范圍過濾 + 函數計算(小數據量可用)

如果查詢時間范圍較?。ㄈ缫恢埽?,MySQL 會先根據 visit_date 的索引過濾出該周數據,再計算 WEEKDAY。此時性能尚可。

-- 假設查詢2025-05-12到2025-05-18這一周的數據
SELECT DATE(visit_date), COUNT(*)
FROM visits
WHERE visit_date BETWEEN '2025-05-12 00:00:00' AND '2025-05-18 23:59:59'
  AND WEEKDAY(visit_date) <= 4
GROUP BY DATE(visit_date);

3.2 方案二:虛擬列 + 函數索引(MySQL 8.0+)

MySQL 8.0 支持函數索引,可以直接在表達式上創(chuàng)建索引,無需修改表結構。

-- 創(chuàng)建函數索引(直接對 WEEKDAY(visit_date) 建立索引)
CREATE INDEX idx_visit_weekday ON visits ((WEEKDAY(visit_date)));

查詢時索引會自動生效:

SELECT DATE(visit_date), COUNT(*)
FROM visits
WHERE WEEKDAY(visit_date) <= 4
GROUP BY DATE(visit_date);

注意:函數索引要求 MySQL 8.0.13+,并且函數必須標記為 DETERMINISTIC(如 WEEKDAY 本身是確定性的)。

3.3 方案三:存儲生成列(虛擬列) + 普通索引(兼容更廣)

對于 MySQL 5.7 或需要兼容更廣泛版本的場景,可以增加一個虛擬列存儲星期幾,并對該列建立索引。

-- 添加虛擬列(不占用額外存儲,實時計算)
ALTER TABLE visits 
ADD COLUMN weekday_val TINYINT 
GENERATED ALWAYS AS (WEEKDAY(visit_date)) STORED;  -- 或 VIRTUAL

-- 為虛擬列創(chuàng)建索引
CREATE INDEX idx_weekday ON visits(weekday_val);

-- 查詢時使用虛擬列
SELECT DATE(visit_date), COUNT(*)
FROM visits
WHERE weekday_val <= 4
GROUP BY DATE(visit_date);
  • STORED:物理存儲,占用空間但查詢稍快。
  • VIRTUAL:不占用空間,每次讀取時計算,但索引仍然可用(8.0 前 VIRTUAL 列索引有限制,建議用 STORED)。

3.4 方案四:預聚合匯總表(終極性能)

如果統計需求固定為“按日統計工作日數據”,可以維護一張日匯總表,通過定時任務或觸發(fā)器增量更新。

CREATE TABLE visits_daily_summary (
    visit_date DATE PRIMARY KEY,
    total_count INT DEFAULT 0,
    weekday_count INT DEFAULT 0,
    weekend_count INT DEFAULT 0,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

增量更新邏輯(每日凌晨執(zhí)行或每筆寫入時更新):

INSERT INTO visits_daily_summary (visit_date, total_count, weekday_count)
SELECT 
    DATE(visit_date),
    COUNT(*),
    SUM(WEEKDAY(visit_date) <= 4)
FROM visits
WHERE visit_date >= CURDATE() - INTERVAL 1 DAY
  AND visit_date < CURDATE()
GROUP BY DATE(visit_date)
ON DUPLICATE KEY UPDATE
    total_count = total_count + VALUES(total_count),
    weekday_count = weekday_count + VALUES(weekday_count);

查詢時直接讀匯總表,毫秒級響應,且完全避免函數計算。

四、方法選擇流程圖

五、常見陷阱與注意事項

時區(qū)問題WEEKDAY() 基于會話時區(qū),如果數據時間是 UTC,查詢時需轉換 CONVERT_TZ。

跨年周WEEKDAY 只判斷星期幾,不關心周數。若需按自然周統計(周一到周日),需結合 YEARWEEK()

NULL 值visit_date 應為 NOT NULL,否則 WEEKDAY(NULL) 返回 NULL,條件不成立。

性能誤區(qū):即使使用函數索引,WHERE WEEKDAY(date) <= 4 AND date BETWEEN ... 仍可能部分走索引。應分析 EXPLAIN 確認。

六、綜合示例:統計某月的工作日日均訪問量

-- 查詢 2025年5月 工作日的日均訪問量(使用虛擬列方案)
SELECT 
    COUNT(*) / COUNT(DISTINCT DATE(visit_date)) AS avg_weekday_visits
FROM visits
WHERE visit_date >= '2025-05-01' 
  AND visit_date < '2025-06-01'
  AND weekday_val <= 4;   -- 假設已添加虛擬列并建立索引

七、總結

方法適用場景索引利用開發(fā)成本維護成本
WEEKDAY() 直接過濾臨時查詢、小表? 全表掃描
函數索引 (8.0+)中等表,不想改結構? 高效
虛擬列 + 索引5.7 環(huán)境,中等表? 高效
預聚合表大表、高頻統計? 極快中(需 ETL)

推薦策略

  • 開發(fā)測試或低并發(fā)場景:直接使用 WEEKDAY(),簡單可靠。
  • 生產環(huán)境百萬級數據:采用虛擬列 + 索引(兼容性好)。
  • 實時大屏或 API 高頻調用:使用預聚合表物化視圖。

到此這篇關于MySQL實現優(yōu)雅統計工作日(周一至周五)數據的文章就介紹到這了,更多相關MySQL統計工作日數據內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySql中使用INSERT INTO語句更新多條數據的例子

    MySql中使用INSERT INTO語句更新多條數據的例子

    這篇文章主要介紹了MySql中使用INSERT INTO語句更新多條數據的例子,MySQL的特有語法,需要的朋友可以參考下
    2014-06-06
  • Mysql Error 1826:Duplicate foreign key constraint錯誤問題及解決

    Mysql Error 1826:Duplicate foreign key&n

    MySQL1826錯誤是由于在創(chuàng)建表時,外鍵索引名重復導致的,解決辦法是在創(chuàng)建外鍵時指定不同的索引名,或修改ForeignKeyName,此問題需注意索引和外鍵名稱的唯一性
    2026-05-05
  • 值得收藏的mysql常用命令集錦

    值得收藏的mysql常用命令集錦

    這篇文章主要為大家整理了mysql常用命令匯總,連接Mysql、修改mysql密碼、數據庫的創(chuàng)建刪除等,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • mysql配置SSL證書登錄的實現

    mysql配置SSL證書登錄的實現

    應國家等級保護三級安全要求,mysql 的 ssl 需要安全證書加密,本文主要介紹了mysql配置SSL證書登錄,感興趣的可以了解一下
    2021-09-09
  • 一篇文章掌握MySQL的索引查詢優(yōu)化技巧

    一篇文章掌握MySQL的索引查詢優(yōu)化技巧

    這篇文章主要給大家介紹了關于如何通過一篇文章掌握MySQL的索引查詢優(yōu)化技巧,文中通過示例代碼介紹的非常詳細,對大家的學習或者使用MySQL具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-07-07
  • mysql數據庫您要的常見日期查詢方法總結

    mysql數據庫您要的常見日期查詢方法總結

    這篇文章主要介紹了MySQL中常用日期查詢的20種方法,包括查詢今天、昨天、近7天、近30天等數據,以及查詢特定日期的周、月、季度和年份數據,需要的朋友可以參考下
    2025-02-02
  • MySQL基于SSL安全連接的主從復制(過程詳解)

    MySQL基于SSL安全連接的主從復制(過程詳解)

    SSL(Secure Sockets Layer 安全套接層),及其繼任者傳輸層安全(Transport Layer Security,TLS)是為網絡通信提供安全及數據完整性的一種安全協議,這篇文章主要介紹了MySQL基于SSL安全連接的主從復制,需要的朋友可以參考下
    2023-04-04
  • 深入探尋mysql自增列導致主鍵重復問題的原因

    深入探尋mysql自增列導致主鍵重復問題的原因

    前幾天開發(fā)的同事反饋一個利用load data infile命令導入數據主鍵沖突的問題,分析后確定這個問題可能是mysql的一個bug,這里提出來給大家分享下。以免以后有童鞋遇到類似問題百思不得其解,難以入眠,哈哈。
    2014-08-08
  • 簡述MySQL與Oracle的區(qū)別

    簡述MySQL與Oracle的區(qū)別

    Oracle是大型數據庫而Mysql是中小型數據庫,Oracle市場占有率達40%,Mysql只有20%左右,同時Mysql是開源的而Oracle價格非常高
    2017-06-06
  • 一文帶你了解MySQL四大類日志

    一文帶你了解MySQL四大類日志

    在MySQL中日志文件可以分為4種:二進制日志文件、錯誤日志文件、通用查詢日志文件和慢查詢日志文件,下面這篇文章主要給大家介紹了關于MySQL四大類日志的相關資料,需要的朋友可以參考下
    2023-04-04

最新評論

长阳| 曲阳县| 东乌珠穆沁旗| 盐津县| 张家界市| 志丹县| 邢台县| 通城县| 沐川县| 师宗县| 东乡| 陈巴尔虎旗| 布拖县| 谢通门县| 岐山县| 兴业县| 威信县| 沁阳市| 阿坝县| 桐柏县| 乌兰浩特市| 民和| 丹寨县| 商丘市| 台南市| 湖南省| 新乡市| 临朐县| 塔河县| 微博| 中山市| 青州市| 永胜县| 沁源县| 永新县| 和平区| 舟山市| 双牌县| 宣武区| 绥中县| 赤壁市|