【问题标题】:MySQL week number with specific first day of the week具有特定一周第一天的 MySQL 周数
【发布时间】:2021-10-18 21:38:28
【问题描述】:

使用 MySQL WEEK 函数,我可以将一周的第一天设置为星期日或星期一。但是如果我需要将它设置为其他日期呢?

这样做的原因是,我们的客户每周都会参加具有特定“签到日”的在线计划。有些人会是星期一,有些人会是星期二,有些人会是星期三等等,我们需要查看每周多次签到的平均值。

如果总是周日和周一,我可以这样做:

SELECT YEAR(timestamp) AS year, WEEK(timestamp,1) AS week ... GROUP BY year, week

但是有成千上万的客户,我需要获取每个客户的每周平均值,但是每个客户都有自己一周的第一天——从周一到周日、周三到周二、周六到周五等等。

有什么想法可以做到这一点吗?

感谢您的帮助!

【问题讨论】:

  • 我认为没有内置任何东西。因此您需要计算一年中每个工作日的第一个日期,然后计算周差并使用它。
  • 第一天是否存储在同一个表中?是时间戳吗?这是该客户在表格中的第一次出现吗?
  • 感谢@Scratte,它不在同一个表中,但我们可以通过连接添加它并在同一个查询中访问它。或者我们可以在运行查询之前将它放在一个变量中,该变量可以插入到查询的任何位置。它作为 DATETIME 存储在另一个表中,称为“entry_due_at”,例如“2021-08-16 12:00:00”。
  • OK.. 所以我认为客户端是 where 子句的一部分?您不是同时为所有客户提取这些数据吗?
  • @Scratte 是的,没错。我们总是一次只显示一个客户的数据,因此每次运行查询时,所有记录的 entry_due_at 都相同。

标签: mysql mysql-8.0 week-number


【解决方案1】:

我将您的时间戳称为 time,以免将其与数据类型混淆:

CREATE TABLE clientdates(client VARCHAR(20),
                         time   TIMESTAMP)

我建议您从时间中减去 DAYOFWEEK("check-in day"),您在 cmets 中将其称为 entry_due_at。然后您将获得 WEEK() 工作所需的偏移量:

SET @client := 'client2';

-- in my example I just picked the first date the client had an entry
SELECT @weekday := DAYOFWEEK(min(time)) - 1 -- need 0 to 6
  FROM clientdates
 WHERE client = @client;

SELECT client,
       @weekday,
       YEAR(time) AS year,
       WEEK(time - INTERVAL @weekday DAY) AS week_offset,
       count(*)
  FROM clientdates
 WHERE client = @client
 GROUP BY client, year, week_offset

使用这些数据运行它,这将是星期四的第一天:

INSERT INTO clientdates
  VALUES ('client2', '2021-08-19 04:14:07.9'),
         ('client2', '2021-08-20 04:14:07.9'),
         ('client2', '2021-08-21 04:14:07.9'),
         ('client2', '2021-08-22 04:14:07.9'),
         ('client2', '2021-08-23 04:14:07.9'),
         ('client2', '2021-08-24 04:14:07.9'),
         ('client2', '2021-08-25 04:14:07.9'),
         ('client2', '2021-08-26 04:14:07.9'),
         ('client2', '2021-08-27 04:14:07.9'),
         ('client2', '2021-08-28 04:14:07.9'),
         ('client2', '2021-08-29 04:14:07.9');

我得到这个结果:

client @weekday year week_offset count(*)
client2 2 2021 33 7
client2 2 2021 34 4

如果您需要改用 WEEK(time, 1),则在获取 @weekday 的值时只需减去 2 而不是 1,因为您需要星期一而不是星期日获得零索引值。


dbfiddle

【讨论】:

  • 完美运行,完全符合需要,非常感谢您对 Scratte 的帮助!
  • @Matt 不客气 :) 请注意,人们用“谢谢”标记 cmets。所以这些cmets随时都可能去。
  • 不错的解决方案 ;) 还在这里哈哈哈
  • @GucciBananaKing99 很高兴听到 :) 我希望你留下 :)
猜你喜欢
  • 1970-01-01
  • 2019-04-24
  • 2012-11-22
  • 2017-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
  • 1970-01-01
相关资源
最近更新 更多