MySQL WEEKOFYEAR() 函数用法与实例

MySQL 中的 WEEKOFYEAR() 函数可以帮助我们从日期或日期时间值中提取周数。

发布于

MySQL 中的 WEEKDAY() 函数是一个简单但实用的日期函数,它专门用来获取日期对应的星期索引。与类似的 DAYOFWEEK() 函数不同,WEEKDAY() 采用更加符合编程习惯的索引方式(周一为 0,周日为 6),特别适合需要在应用程序中进行日期逻辑处理的场景。本文将全面介绍这个函数的使用方法和实际应用案例。

WEEKDAY() 函数基本介绍

WEEKDAY() 函数返回日期的星期索引值,遵循以下规则:

  • 周一 = 0
  • 周二 = 1
  • 周三 = 2
  • 周四 = 3
  • 周五 = 4
  • 周六 = 5
  • 周日 = 6

这个编号系统与 DAYOFWEEK() 函数不同(后者周日=1,周六=7),更符合国际标准 ISO 8601 的周计数方式,也更容易在程序逻辑中使用。

基本语法非常简单:

WEEKDAY(date)

其中 date 参数可以是日期、日期时间或能被解析为日期的字符串。

基础用法示例

让我们看几个最基本的用法示例:

获取当前日期的星期索引:

SELECT WEEKDAY(NOW());

查询特定日期的星期几:

SELECT WEEKDAY('2023-05-15');

处理日期时间值:

SELECT WEEKDAY('2023-05-15 14:30:00');

这些查询都会返回一个 0-6 之间的整数,对应周一到周日。

与 DAYOFWEEK() 的区别

很多开发者会混淆 WEEKDAY()DAYOFWEEK() 函数,它们的主要区别在于:

  1. 起始值不同:

    • WEEKDAY():周一=0,周日=6
    • DAYOFWEEK():周日=1,周六=7
  2. 标准不同:

    • WEEKDAY() 符合 ISO 标准
    • DAYOFWEEK() 更符合西方传统习惯

示例对比:

SELECT
    WEEKDAY('2023-05-15') AS weekday_index,
    DAYOFWEEK('2023-05-15') AS dayofweek_index;

实际应用场景

WEEKDAY() 函数在实际业务中有多种应用方式。

筛选特定工作日的数据

假设我们需要查询所有周四创建的订单:

SELECT *
FROM orders
WHERE WEEKDAY(created_at) = 3;

计算工作日天数

统计某个月内工作日的数量(假设工作日为周一到周五):

SELECT
    COUNT(*) AS work_days
FROM
    calendar
WHERE
    YEAR(date) = 2023
    AND MONTH(date) = 5
    AND WEEKDAY(date) BETWEEN 0 AND 4;

生成友好的星期显示

结合 CASE 语句生成易读的星期名称:

SELECT
    date,
    CASE WEEKDAY(date)
        WHEN 0 THEN 'Monday'
        WHEN 1 THEN 'Tuesday'
        WHEN 2 THEN 'Wednesday'
        WHEN 3 THEN 'Thursday'
        WHEN 4 THEN 'Friday'
        WHEN 5 THEN 'Saturday'
        WHEN 6 THEN 'Sunday'
    END AS day_name
FROM events;

与其他日期函数结合使用

WEEKDAY() 经常与其他日期函数组合使用,实现更复杂的功能。

计算下一个工作日

假设我们需要计算某个日期后的下一个工作日(周一到周五):

SELECT
    DATE_ADD('2023-05-15',
    INTERVAL
        CASE WEEKDAY('2023-05-15')
            WHEN 4 THEN 3  -- 周五+3天=周一
            WHEN 5 THEN 2  -- 周六+2天=周一
            ELSE 1          -- 其他+1天
        END DAY) AS next_workday;

统计每周各天的活跃用户

分析用户活跃度的星期分布:

SELECT
    WEEKDAY(login_time) AS day_index,
    COUNT(DISTINCT user_id) AS active_users
FROM
    user_logins
GROUP BY
    day_index
ORDER BY
    day_index;

处理特殊业务逻辑

不同业务对工作日的定义可能不同,WEEKDAY() 可以帮助实现这些特殊逻辑。

自定义周末定义

某些国家周末是周五和周六:

-- 筛选非周末日(周日到周四)
SELECT *
FROM transactions
WHERE WEEKDAY(transaction_date) IN (0,1,2,3,6);

计算工作日差异

计算两个日期之间的工作日天数(简单版):

SELECT
    SUM(WEEKDAY(date) BETWEEN 0 AND 4) AS work_days
FROM
    (SELECT DATE_ADD('2023-05-01', INTERVAL n DAY) AS date
     FROM numbers WHERE n <= DATEDIFF('2023-05-31', '2023-05-01')) AS date_range;

性能考虑与优化

在大数据量下使用 WEEKDAY() 时,需要注意:

  1. 避免在列上直接使用函数,这会导致索引失效:

    -- 不推荐(无法使用索引)
    SELECT * FROM orders WHERE WEEKDAY(created_at) = 0;
    
    -- 推荐(可以使用索引)
    SELECT * FROM orders WHERE created_at BETWEEN '2023-05-01' AND '2023-05-07'
    AND WEEKDAY(created_at) = 0;
    
  2. 考虑使用持久化计算列(MySQL 5.7+):

    ALTER TABLE orders ADD COLUMN weekday_index TINYINT
    GENERATED ALWAYS AS (WEEKDAY(created_at)) STORED;
    

总结

MySQL 的 WEEKDAY() 函数提供了简单有效的方式来获取日期的星期索引,特别适合需要基于工作日进行业务逻辑处理的场景。与 DAYOFWEEK() 相比,它采用更符合编程习惯的编号方式(周一为 0),在实现国际化应用时尤其有用。通过与其他日期函数结合,可以解决各种复杂的日期计算问题。在实际使用时,记住考虑性能影响,特别是在大数据量表上使用时,合理的设计可以避免全表扫描,提高查询效率。