
在數(shù)據(jù)處理與業(yè)務(wù)分析中,日期數(shù)據(jù)是連接 “業(yè)務(wù)行為” 與 “時(shí)間維度” 的核心紐帶 —— 無(wú)論是統(tǒng)計(jì)月度銷(xiāo)售額、篩選季度活躍用戶(hù),還是清洗格式混亂的時(shí)間戳,都離不開(kāi) “日期截取” 操作。SQL 作為數(shù)據(jù)查詢(xún)與處理的核心語(yǔ)言,提供了適配不同數(shù)據(jù)庫(kù)(MySQL、SQL Server、Oracle 等)的日期截取函數(shù),這些函數(shù)看似簡(jiǎn)單,卻直接決定了數(shù)據(jù)統(tǒng)計(jì)的準(zhǔn)確性與效率。本文將從業(yè)務(wù)需求出發(fā),系統(tǒng)梳理 SQL 日期截取的核心方法、典型場(chǎng)景與實(shí)戰(zhàn)技巧,幫助開(kāi)發(fā)者規(guī)避常見(jiàn)誤區(qū),高效處理日期數(shù)據(jù)。
日期數(shù)據(jù)在數(shù)據(jù)庫(kù)中通常以 “datetime”“date”“timestamp” 等類(lèi)型存儲(chǔ),包含 “年、月、日、時(shí)、分、秒” 甚至毫秒級(jí)信息。但實(shí)際業(yè)務(wù)分析中,往往不需要完整的時(shí)間維度 —— 例如 “統(tǒng)計(jì)每月訂單量” 只需 “年 - 月” 信息,“篩選上周注冊(cè)用戶(hù)” 只需定位 “周” 維度。這種 “從完整日期中提取目標(biāo)時(shí)間單元” 的需求,正是 SQL 日期截取的核心應(yīng)用場(chǎng)景,具體可分為三類(lèi):
業(yè)務(wù)中最常見(jiàn)的需求,需按 “日、周、月、季度、年” 等固定時(shí)間單元聚合指標(biāo)(如銷(xiāo)量、用戶(hù)數(shù)、收入)。例如:
電商平臺(tái)需 “按月份統(tǒng)計(jì) 2024 年各品類(lèi)銷(xiāo)售額”,需從訂單表的 “下單時(shí)間(create_time)” 中截取 “年 - 月”;
人力資源系統(tǒng)需 “按季度統(tǒng)計(jì)新員工入職人數(shù)”,需從員工表的 “入職時(shí)間(hire_date)” 中截取 “年 - 季度”。
若不進(jìn)行日期截取,直接對(duì)完整 datetime 字段分組,會(huì)因 “時(shí)分秒” 差異導(dǎo)致同一時(shí)間單元的數(shù)據(jù)被拆分(如 2024-05-01 09:30:00 與 2024-05-01 14:15:00 會(huì)被視為兩個(gè)不同分組),統(tǒng)計(jì)結(jié)果完全失真。
在 WHERE 條件中,通過(guò)日期截取可快速篩選特定時(shí)間單元的數(shù)據(jù),避免復(fù)雜的日期范圍計(jì)算。例如:
篩選 “2024 年 3 月所有退款訂單”,無(wú)需寫(xiě)create_time BETWEEN '2024-03-01 00:00:00' AND '2024-03-31 23:59:59'
,直接截取 “年 - 月” 并匹配 “2024-03” 即可;
定位 “本周內(nèi)登錄過(guò)的用戶(hù)”,通過(guò)截取 “周” 維度,可自動(dòng)適配不同周的日期范圍(無(wú)需手動(dòng)計(jì)算周一至周日的具體日期)。
當(dāng)數(shù)據(jù)庫(kù)中存在格式混亂的日期數(shù)據(jù)(如部分為 “20240520” 字符串,部分為 “2024-05-20 16:40:00” datetime),或需將不同精度的日期統(tǒng)一為相同維度(如將 timestamp 統(tǒng)一為 “年 - 日”)時(shí),日期截取是核心清洗手段。例如:
將字符串格式 “20240520” 轉(zhuǎn)換為 “2024-05-20” 日期類(lèi)型后,截取 “年 - 月” 用于后續(xù)統(tǒng)計(jì);
去除日志表中時(shí)間戳的 “時(shí)分秒”,僅保留 “日期” 維度,減少數(shù)據(jù)冗余。
不同數(shù)據(jù)庫(kù)(MySQL、SQL Server、Oracle)的日期截取函數(shù)設(shè)計(jì)不同,但核心邏輯一致 ——“指定目標(biāo)日期字段 + 提取所需時(shí)間單元”。以下梳理各數(shù)據(jù)庫(kù)最常用的截取函數(shù)及典型示例(假設(shè)存在表orders
,含字段create_time
(datetime 類(lèi)型),存儲(chǔ)訂單創(chuàng)建時(shí)間)。
MySQL 中日期截取的核心優(yōu)勢(shì)是支持自定義格式,主要依賴(lài)DATE_FORMAT()
函數(shù);若需提取單個(gè)時(shí)間單元(如月份、季度),可使用EXTRACT()
函數(shù),操作更簡(jiǎn)潔。
通過(guò)指定格式模板,可提取任意組合的時(shí)間單元,常用模板符號(hào)及示例如下:
格式符號(hào) | 含義 | 示例(針對(duì) 2024-05-20 16:40:30) | 函數(shù)調(diào)用與結(jié)果 |
---|---|---|---|
%Y | 4 位年份 | 2024 | DATE_FORMAT(create_time, '%Y') → 2024 |
%m | 2 位月份(01-12) | 05 | DATE_FORMAT(create_time, '%Y-%m') → 2024-05 |
%d | 2 位日期(01-31) | 20 | DATE_FORMAT(create_time, '%Y-%m-%d') → 2024-05-20 |
%H | 24 小時(shí)制小時(shí)(00-23) | 16 | DATE_FORMAT(create_time, '%H:%i') → 16:40 |
%U | 周(周日為一周第一天,00-53) | 20 | DATE_FORMAT(create_time, '%Y-%U') → 2024-20 |
%q | 季度(1-4) | 2 | DATE_FORMAT(create_time, '%Y-Q%q') → 2024-Q2 |
實(shí)戰(zhàn)示例:統(tǒng)計(jì) 2024 年各月訂單量
SELECT 
  DATE_FORMAT(create_time, '%Y-%m') AS order_month, -- 截取“年-月”作為分組維度
  COUNT(order_id) AS order_count -- 統(tǒng)計(jì)每月訂單量
FROM orders
WHERE DATE_FORMAT(create_time, '%Y') = '2024' -- 篩選2024年數(shù)據(jù)
GROUP BY order_month
ORDER BY order_month;
當(dāng)僅需獲取 “月份”“季度” 等單個(gè)維度時(shí),EXTRACT()
比DATE_FORMAT()
更簡(jiǎn)潔,支持的時(shí)間單元包括YEAR
(年)、MONTH
(月)、QUARTER
(季度)、WEEK
(周)等。
示例:提取訂單創(chuàng)建時(shí)間的季度與月份
SELECT 
  EXTRACT(YEAR FROM create_time) AS order_year, -- 提取年份
  EXTRACT(QUARTER FROM create_time) AS order_qtr, -- 提取季度
  EXTRACT(MONTH FROM create_time) AS order_month -- 提取月份
FROM orders
LIMIT 10;
SQL Server 的日期截取函數(shù)分為兩類(lèi):DATEPART()
用于提取時(shí)間單元的數(shù)值(如月份返回 “5” 而非 “05”),FORMAT()
支持自定義格式(類(lèi)似 MySQL 的DATE_FORMAT()
),需根據(jù)場(chǎng)景選擇。
常用時(shí)間單元參數(shù)及示例(針對(duì) 2024-05-20 16:40:30):
時(shí)間單元參數(shù) | 含義 | 示例結(jié)果 | 函數(shù)調(diào)用 |
---|---|---|---|
year | 年份 | 2024 | DATEPART(year, create_time) |
month | 月份 | 5 | DATEPART(month, create_time) |
day | 日期 | 20 | DATEPART(day, create_time) |
week | 周(周一為第一天) | 21 | DATEPART(week, create_time) |
quarter | 季度 | 2 | DATEPART(quarter, create_time) |
實(shí)戰(zhàn)示例:篩選 2024 年第 2 季度的訂單
SELECT order_id, create_time
FROM orders
WHERE 
  DATEPART(year, create_time) = 2024 
  AND DATEPART(quarter, create_time) = 2; -- 篩選2024年Q2
需注意:FORMAT()
返回字符串類(lèi)型,格式模板使用 “yyyy”“MM”“dd” 等符號(hào),與 MySQL 的DATE_FORMAT()
符號(hào)不同。
示例:將創(chuàng)建時(shí)間格式化為 “年 - 月 - 日 時(shí):分”
SELECT 
  order_id,
  FORMAT(create_time, 'yyyy-MM-dd HH:mm') AS formatted_create_time
FROM orders;
Oracle 的日期截取以TRUNC()
(截?cái)嗳掌?,保留目?biāo)維度)和EXTRACT()
(提取單個(gè)時(shí)間單元)為主,其中TRUNC()
是最常用的函數(shù) —— 它會(huì)將截?cái)嗪蟮臅r(shí)間設(shè)為 “00:00:00”,適合日期維度的統(tǒng)一。
若不指定時(shí)間單元,默認(rèn)截?cái)嘀?“日期”(去除時(shí)分秒);指定單元后,保留該維度及更高維度(如截?cái)嘀?“月”,則保留 “年 - 月”,日設(shè)為 1)。
常用時(shí)間單元及示例(針對(duì) 2024-05-20 16:40:30):
時(shí)間單元 | 含義 | 截?cái)嘟Y(jié)果 | 函數(shù)調(diào)用 |
---|---|---|---|
'' | 默認(rèn)(日期) | 2024-05-20 00:00:00 | TRUNC(create_time) |
'MM' | 月份 | 2024-05-01 00:00:00 | TRUNC(create_time, 'MM') |
'Q' | 季度 | 2024-04-01 00:00:00 | TRUNC(create_time, 'Q') |
'YYYY' | 年份 | 2024-01-01 00:00:00 | TRUNC(create_time, 'YYYY') |
'IW' | 周(ISO 標(biāo)準(zhǔn),周一為第一天) | 2024-05-20 00:00:00(假設(shè)該日為周一) | TRUNC(create_time, 'IW') |
實(shí)戰(zhàn)示例:統(tǒng)計(jì) 2024 年各季度訂單總金額
SELECT 
  TRUNC(create_time, 'Q') AS order_qtr, -- 截?cái)嘀良径龋鳛榉纸M維度
  SUM(order_amount) AS total_amount -- 統(tǒng)計(jì)季度總金額
FROM orders
WHERE TRUNC(create_time, 'YYYY') = TO_DATE('2024-01-01', 'YYYY-MM-DD')
GROUP BY order_qtr
ORDER BY order_qtr;
示例:提取訂單創(chuàng)建時(shí)間的年份和月份
SELECT 
  EXTRACT(YEAR FROM create_time) AS order_year,
  EXTRACT(MONTH FROM create_time) AS order_month
FROM orders;
基礎(chǔ)截取方法可滿(mǎn)足簡(jiǎn)單需求,但面對(duì) “跨年度周統(tǒng)計(jì)”“動(dòng)態(tài)時(shí)間范圍”“大數(shù)據(jù)量查詢(xún)” 等復(fù)雜場(chǎng)景,需結(jié)合進(jìn)階技巧,兼顧準(zhǔn)確性與效率。
不同數(shù)據(jù)庫(kù)對(duì) “周” 的定義不同(如 MySQL 的%U
以周日為一周第一天,Oracle 的IW
按 ISO 標(biāo)準(zhǔn)以周一為第一天),需統(tǒng)一周定義避免統(tǒng)計(jì)偏差。
MySQL 示例:按 ISO 周統(tǒng)計(jì) 2024 年各周訂單量(ISO 周以周一為第一天,第 1 周至少含 4 天)
SELECT 
  CONCAT(YEAR(create_time), '-W', DATE_FORMAT(create_time, '%v')) AS iso_week, -- %v表示ISO周
  COUNT(order_id) AS order_count
FROM orders
WHERE DATE_FORMAT(create_time, '%x') = '2024' -- %x表示ISO周對(duì)應(yīng)的年份
GROUP BY iso_week;
無(wú)需手動(dòng)計(jì)算起始日期,通過(guò)DATE_SUB()
(MySQL)、DATEADD()
(SQL Server/Oracle)結(jié)合日期截取實(shí)現(xiàn)動(dòng)態(tài)篩選。
SQL Server 示例:篩選近 3 個(gè)月訂單
SELECT order_id, create_time
FROM orders
WHERE 
  TRUNC(create_time, 'MM') >= TRUNC(DATEADD(month, -3, GETDATE()), 'MM'); -- GETDATE()獲取當(dāng)前時(shí)間
日期字段若建立索引(如create_time
上的索引),直接在 WHERE 條件中對(duì)該字段使用截取函數(shù)(如DATE_FORMAT(create_time, '%Y-%m') = '2024-05'
),會(huì)導(dǎo)致索引失效 —— 數(shù)據(jù)庫(kù)無(wú)法直接使用索引查找,需全表掃描,大數(shù)據(jù)量下查詢(xún)緩慢。
優(yōu)化方案:將 “函數(shù)作用于字段” 改為 “字段與目標(biāo)值范圍匹配”,利用索引加速查詢(xún)。
反例(索引失效):
-- MySQL:對(duì)create_time使用函數(shù),索引失效
SELECT * FROM orders WHERE DATE_FORMAT(create_time, '%Y-%m') = '2024-05';
正例(利用索引):
-- MySQL:直接匹配日期范圍,索引生效
SELECT * FROM orders 
WHERE create_time BETWEEN '2024-05-01 00:00:00' AND '2024-05-31 23:59:59';
若業(yè)務(wù)中需頻繁按 “年 - 月” 篩選,可在表中新增 “冗余字段”order_month
(存儲(chǔ) “2024-05” 格式),并建立索引,查詢(xún)時(shí)直接匹配該字段,進(jìn)一步提升效率。
當(dāng)日期數(shù)據(jù)為字符串類(lèi)型(如 “20240520”“2024/05/20”)時(shí),需先轉(zhuǎn)換為標(biāo)準(zhǔn) datetime 類(lèi)型,再進(jìn)行截取,避免格式混亂導(dǎo)致的錯(cuò)誤。
MySQL 示例:將字符串 “20240520” 轉(zhuǎn)換為日期并截取 “年 - 月”
SELECT 
  DATE_FORMAT(STR_TO_DATE(order_date_str, '%Y%m%d'), '%Y-%m') AS order_month -- STR_TO_DATE轉(zhuǎn)換格式
FROM orders_str -- 表中order_date_str為字符串類(lèi)型
MySQL 中%m
(2 位月份)與%c
(1 位月份,如 5 而非 05)的區(qū)別:若用%c
分組,“2024-5” 與 “2024-05” 會(huì)被視為兩個(gè)維度,導(dǎo)致統(tǒng)計(jì)拆分;
SQL Server 中FORMAT()
返回字符串,若用 “M”(1 位月份)格式化,后續(xù)排序會(huì)出現(xiàn) “2024-1”“2024-10”“2024-2” 的混亂順序,需用 “MM”(2 位月份)確保排序正確。
若數(shù)據(jù)庫(kù)啟用了時(shí)區(qū)設(shè)置(如 MySQL 的time_zone
參數(shù)),NOW()
(MySQL)、GETDATE()
(SQL Server)獲取的當(dāng)前時(shí)間會(huì)受時(shí)區(qū)影響,截取后可能出現(xiàn) “跨天 / 跨月” 偏差。解決方案:統(tǒng)一數(shù)據(jù)庫(kù)時(shí)區(qū)與業(yè)務(wù)時(shí)區(qū),或在截取時(shí)指定時(shí)區(qū)(如 MySQL 的CONVERT_TZ()
函數(shù))。
對(duì)超大規(guī)模表(千萬(wàn)級(jí)以上),頻繁使用日期截取函數(shù)會(huì)增加 CPU 計(jì)算成本。建議對(duì)高頻統(tǒng)計(jì)維度(如 “年 - 月”“季度”)建立冗余字段,通過(guò) ETL 定時(shí)更新,查詢(xún)時(shí)直接使用冗余字段,平衡 “存儲(chǔ)成本” 與 “查詢(xún)效率”。
SQL 日期截取看似是基礎(chǔ)操作,實(shí)則是連接 “原始日期數(shù)據(jù)” 與 “業(yè)務(wù)時(shí)間維度” 的核心橋梁。它不僅決定了統(tǒng)計(jì)分析的準(zhǔn)確性(如避免跨時(shí)間單元的數(shù)據(jù)拆分),也影響著查詢(xún)效率(如索引利用與否)。無(wú)論是電商的銷(xiāo)售報(bào)表、金融的交易對(duì)賬,還是互聯(lián)網(wǎng)的用戶(hù)行為分析,都需以精準(zhǔn)的日期截取為前提。
掌握不同數(shù)據(jù)庫(kù)的截取函數(shù)差異、結(jié)合業(yè)務(wù)場(chǎng)景選擇合適的方法、規(guī)避索引失效等誤區(qū),是每個(gè)數(shù)據(jù)從業(yè)者的必備技能。隨著數(shù)據(jù)量的增長(zhǎng)與業(yè)務(wù)復(fù)雜度的提升,日期截取也將從 “單一維度提取” 向 “多維度組合”“動(dòng)態(tài)時(shí)間范圍” 演進(jìn),但核心邏輯始終不變 —— 以 “時(shí)間” 為標(biāo)尺,讓數(shù)據(jù)更精準(zhǔn)地服務(wù)于業(yè)務(wù)決策。
數(shù)據(jù)分析咨詢(xún)請(qǐng)掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無(wú)論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢(xún)效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫(kù)管理中,“大表” 始終是性能優(yōu)化繞不開(kāi)的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫(kù)表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動(dòng)態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開(kāi)始提取前,需先判斷 TIF 文件的類(lèi)型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價(jià)值的專(zhuān)業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫(kù)表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫(kù))處理 Excel 數(shù)據(jù)時(shí),“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場(chǎng)景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專(zhuān)業(yè)操盤(pán)手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對(duì)象的 text 與 content:區(qū)別、場(chǎng)景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請(qǐng)求開(kāi)發(fā)時(shí)(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價(jià)值的核心操盤(pán)手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫(kù)表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請(qǐng)求工具對(duì)比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請(qǐng)求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長(zhǎng)浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問(wèn)題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長(zhǎng)浮點(diǎn)數(shù)據(jù)時(shí)的科學(xué)計(jì)數(shù)法問(wèn)題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價(jià)值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營(yíng)問(wèn)題、提升執(zhí)行效率的核心手段,其價(jià)值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過(guò)程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶(hù)體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營(yíng)銷(xiāo)案例:數(shù)據(jù)驅(qū)動(dòng)下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見(jiàn)頂” 的當(dāng)下,精準(zhǔn)營(yíng)銷(xiāo)成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價(jià)值 在數(shù)據(jù)驅(qū)動(dòng)決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類(lèi)分析:從操作實(shí)踐到業(yè)務(wù)價(jià)值挖掘 在數(shù)據(jù)分析場(chǎng)景中,聚類(lèi)分析作為 “無(wú)監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計(jì)模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價(jià)值導(dǎo)向 統(tǒng)計(jì)模型作為數(shù)據(jù)分析的核心工具,并非簡(jiǎn)單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10