MySQL高级函数之:`DAYOFWEEK()` 和 `WEEKDAY()`:其在获取星期几时的应用。

MySQL高级函数之:DAYOFWEEK()WEEKDAY():获取星期几的应用

大家好,今天我们来深入探讨MySQL中两个常用的日期函数:DAYOFWEEK()WEEKDAY()。这两个函数都用于获取给定日期的星期几,但它们返回的值略有不同,理解它们的区别对于编写准确的SQL查询至关重要。

1. DAYOFWEEK() 函数

DAYOFWEEK() 函数返回给定日期的星期几,返回值是一个介于 1 到 7 之间的整数,其中 1 代表星期日,2 代表星期一,以此类推,7 代表星期六。

语法:

DAYOFWEEK(date)

其中 date 可以是日期类型的列名、日期字符串或日期表达式。

示例:

假设我们有一个名为 orders 的表,其中包含订单信息,包括 order_date 列,存储订单的日期。

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    order_date DATE
);

INSERT INTO orders (order_id, order_date) VALUES
(1, '2023-10-26'),  -- 星期四
(2, '2023-10-27'),  -- 星期五
(3, '2023-10-28'),  -- 星期六
(4, '2023-10-29'),  -- 星期日
(5, '2023-10-30'),  -- 星期一
(6, '2023-10-31'),  -- 星期二
(7, '2023-11-01');  -- 星期三

现在,我们可以使用 DAYOFWEEK() 函数来获取每个订单的星期几:

SELECT order_id, order_date, DAYOFWEEK(order_date) AS day_of_week
FROM orders;

查询结果如下:

order_id order_date day_of_week
1 2023-10-26 5
2 2023-10-27 6
3 2023-10-28 7
4 2023-10-29 1
5 2023-10-30 2
6 2023-10-31 3
7 2023-11-01 4

可以看到,DAYOFWEEK() 函数返回了与日期对应的星期几的数字表示。

应用场景:

  • 统计特定星期几的订单数量:
SELECT DAYOFWEEK(order_date) AS day_of_week, COUNT(*) AS order_count
FROM orders
GROUP BY DAYOFWEEK(order_date)
ORDER BY DAYOFWEEK(order_date);
  • 筛选特定星期几的订单:
SELECT *
FROM orders
WHERE DAYOFWEEK(order_date) = 1; -- 筛选星期日的订单

2. WEEKDAY() 函数

WEEKDAY() 函数也返回给定日期的星期几,但返回值是一个介于 0 到 6 之间的整数,其中 0 代表星期一,1 代表星期二,以此类推,6 代表星期日。

语法:

WEEKDAY(date)

其中 date 的含义与 DAYOFWEEK() 函数相同。

示例:

使用与之前相同的 orders 表,我们可以使用 WEEKDAY() 函数来获取每个订单的星期几:

SELECT order_id, order_date, WEEKDAY(order_date) AS weekday
FROM orders;

查询结果如下:

order_id order_date weekday
1 2023-10-26 3
2 2023-10-27 4
3 2023-10-28 5
4 2023-10-29 6
5 2023-10-30 0
6 2023-10-31 1
7 2023-11-01 2

可以看到,WEEKDAY() 函数返回了与日期对应的星期几的数字表示,但星期一从 0 开始计数。

应用场景:

  • 统计特定星期几的订单数量:
SELECT WEEKDAY(order_date) AS weekday, COUNT(*) AS order_count
FROM orders
GROUP BY WEEKDAY(order_date)
ORDER BY WEEKDAY(order_date);
  • 筛选特定星期几的订单:
SELECT *
FROM orders
WHERE WEEKDAY(order_date) = 6; -- 筛选星期日的订单

3. DAYNAME() 函数

虽然不是数字表示,但 DAYNAME() 函数也经常与 DAYOFWEEK()WEEKDAY() 一起使用,它可以直接返回日期的星期几的英文名称。

语法:

DAYNAME(date)

示例:

SELECT order_id, order_date, DAYNAME(order_date) AS day_name
FROM orders;

查询结果如下:

order_id order_date day_name
1 2023-10-26 Thursday
2 2023-10-27 Friday
3 2023-10-28 Saturday
4 2023-10-29 Sunday
5 2023-10-30 Monday
6 2023-10-31 Tuesday
7 2023-11-01 Wednesday

4. DATE_FORMAT() 函数

DATE_FORMAT() 函数可以将日期格式化成各种字符串表示形式,其中也包括星期几的名称。

语法:

DATE_FORMAT(date, format)

其中 format 是一个字符串,用于指定日期的格式。常用的星期几格式符包括:

  • %W: 星期几的全名 (Sunday, Monday, …)
  • %a: 星期几的缩写 (Sun, Mon, …)

示例:

SELECT order_id, order_date, DATE_FORMAT(order_date, '%W') AS day_name_full, DATE_FORMAT(order_date, '%a') AS day_name_short
FROM orders;

查询结果如下:

order_id order_date day_name_full day_name_short
1 2023-10-26 Thursday Thu
2 2023-10-27 Friday Fri
3 2023-10-28 Saturday Sat
4 2023-10-29 Sunday Sun
5 2023-10-30 Monday Mon
6 2023-10-31 Tuesday Tue
7 2023-11-01 Wednesday Wed

5. TO_DAYS()FROM_DAYS() 函数

这两个函数可以将日期转换为一个表示自公元0年1月1日以来的天数的整数,反之亦然。虽然它们本身不直接返回星期几,但可以用来计算两个日期之间的天数差,从而间接推导出星期几。 不过,这种方法通常不如直接使用 DAYOFWEEK()WEEKDAY() 方便。

语法:

TO_DAYS(date)
FROM_DAYS(N)

示例:

SELECT TO_DAYS('2023-11-01');  -- 返回 739182
SELECT FROM_DAYS(739182);  -- 返回 2023-11-01

6. 区别和选择:DAYOFWEEK() vs WEEKDAY()

特性 DAYOFWEEK() WEEKDAY()
返回值范围 1-7 (1 代表星期日) 0-6 (0 代表星期一)
星期日 1 6
星期一 2 0
使用场景 需要以星期日作为一周的开始时 需要以星期一作为一周的开始时

如何选择:

  • 如果你的业务逻辑需要以星期日作为一周的开始(例如,某些国家的日历习惯),则应该使用 DAYOFWEEK()
  • 如果你的业务逻辑需要以星期一作为一周的开始(例如,ISO 8601 标准),则应该使用 WEEKDAY()
  • 如果仅仅需要星期几的英文名称,使用 DAYNAME() 或者 DATE_FORMAT()

7. 结合其他日期函数进行更复杂的操作

这些函数可以与其他日期函数结合使用,实现更复杂的日期计算和分析。

示例1:计算每个月第一个星期一的日期

SELECT
    DATE_ADD(
        LAST_DAY(DATE_SUB('2024-01-15', INTERVAL (DAYOFWEEK('2024-01-15')-2) DAY)),  -- 找到上个月的最后一个星期日
        INTERVAL 1 DAY
    ) AS first_monday;

-- 更通用的方法,计算任意日期所在月份的第一个星期一
SELECT
    DATE_ADD(
        LAST_DAY(DATE_SUB(your_date_column, INTERVAL (DAYOFWEEK(your_date_column)-2) DAY)),
        INTERVAL 1 DAY
    ) AS first_monday;

解释:

  1. your_date_column 替换为你需要计算的日期列或具体的日期。
  2. DAYOFWEEK(your_date_column) 返回 your_date_column 是星期几(1-7,星期日为1)。
  3. DAYOFWEEK(your_date_column)-2 计算出 your_date_column 距离星期一有多少天。 如果结果是负数,表示 your_date_column 本身就在星期一之前。
  4. DATE_SUB(your_date_column, INTERVAL (DAYOFWEEK(your_date_column)-2) DAY)your_date_column 减去计算出的天数,得到最接近 your_date_column 的上一个星期日。
  5. LAST_DAY(...) 返回上一步计算出的星期日所在月份的最后一天。
  6. DATE_ADD(..., INTERVAL 1 DAY) 在上一步的结果上加一天,得到下个月的第一天。因为第五步已经确保了是上个月的最后一个星期日,加一天后必然是下个月的第一个星期一。

示例2:计算某个日期所在的周的起始日期(星期一)

SELECT DATE(your_date_column - INTERVAL (WEEKDAY(your_date_column)) DAY) AS week_start;

解释:

  1. WEEKDAY(your_date_column) 返回 your_date_column 是星期几(0-6,星期一为0)。
  2. your_date_column - INTERVAL (WEEKDAY(your_date_column)) DAYyour_date_column 减去相应的天数,得到该周的星期一。
  3. DATE(...) 提取日期部分,去除时间。

示例3:计算某个月有多少个星期五

SELECT SUM(CASE WHEN DAYOFWEEK(date) = 6 THEN 1 ELSE 0 END) AS friday_count
FROM (
    SELECT CURDATE() + INTERVAL (n - 1) DAY AS date
    FROM (
        SELECT a.n + b.n * 10 AS n
        FROM
        (SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) AS a,
        (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) AS b
    ) numbers
    WHERE MONTH(CURDATE() + INTERVAL (n - 1) DAY) = MONTH(CURDATE())
) AS dates_in_month;

解释:

  1. 内层SELECT生成一个数字序列,范围从1到31(足以覆盖一个月的所有天数)。
  2. 中间的SELECT生成一个日期序列,从当前日期开始,依次加上天数,形成一个包含一个月所有日期的表。
  3. 外层SELECT使用DAYOFWEEK()函数判断每个日期是否为星期五,如果是,则计数加1。
  4. SUM()函数计算所有星期五的数量。

这些示例仅仅是冰山一角,你可以根据自己的需求,灵活运用这些日期函数,实现各种复杂的日期计算和分析。

总结:选择合适的函数来获取星期几

DAYOFWEEK()WEEKDAY() 都是用于获取星期几的函数,但它们的返回值不同。DAYOFWEEK() 从星期日开始计数,WEEKDAY() 从星期一开始计数。根据你的业务需求选择合适的函数,可以更方便地进行日期计算和分析。DAYNAME()DATE_FORMAT() 可以直接返回星期几的名称。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注