Oracle的表服务器提供内置函数TRUNC(timestamp,'DY')
。此函数将上一个星期日的任何时间戳转换为午夜。在MySQL中执行此操作的最佳方法是什么?
Oracle还提供TRUNC(timestamp,'MM')
将时间戳转换为发生月份的第一天的午夜。在MySQL中,这个很简单:
TIMESTAMP(DATE_FORMAT(timestamp, '%Y-%m-01'))
但这个DATE_FORMAT
技巧几周不会奏效。我知道WEEK(timestamp)
函数,但我真的不想要一年中的周数;这个东西是多年的工作。
答案 0 :(得分:98)
您可以同时使用YEAR(timestamp)
和WEEK(timestamp)
,并在SELECT
和GROUP BY
子句中使用这两个表达式。
不是太优雅,但功能性......
当然,您也可以将这两个日期部分组合在一个表达式中,例如
SELECT CONCAT(YEAR(timestamp), '/', WEEK(timestamp)), etc...
FROM ...
WHERE ..
GROUP BY CONCAT(YEAR(timestamp), '/', WEEK(timestamp))
编辑:正如Martin xx指出的那样,你也可以使用YEARWEEK(mysqldatefield)
函数,虽然它的输出不如上面较长的公式那样友好。
编辑2 [3年半以后!]:
YEARWEEK(mysqldatefield)
将可选的第二个参数(mode
)设置为0或2可能是完整周聚合的最佳方式(即包括跨越1月1日的几周) ),如果那是你想要的。最初在这个答案中提出的YEAR() / WEEK()
方法将这种“跨越”周的汇总数据分成两部分:一年与前一年,一年与新年相同。
每年都要做一个简洁的工作,最多需要两个部分周,一个是两端,通常需要会计等等。YEAR() / WEEK()
方法更好。
答案 1 :(得分:25)
上面接受的答案对我不起作用,因为它按字母顺序排序了几周,而不是按时间顺序排列:
2012/1
2012/10
2012/11
...
2012/19
2012/2
这是我按周计算和分组的解决方案:
SELECT CONCAT(YEAR(date), '/', WEEK(date)) AS week_name,
YEAR(date), WEEK(date), COUNT(*)
FROM column_name
GROUP BY week_name
ORDER BY YEAR(DATE) ASC, WEEK(date) ASC
生成:
YEAR/WEEK YEAR WEEK COUNT
2011/51 2011 51 15
2011/52 2011 52 14
2012/1 2012 1 20
2012/2 2012 2 14
2012/3 2012 3 19
2012/4 2012 4 19
答案 2 :(得分:23)
想出来......这有点麻烦,但现在就是。
FROM_DAYS(TO_DAYS(TIMESTAMP) -MOD(TO_DAYS(TIMESTAMP) -1, 7))
而且,如果您的商家规则规定您的周数从周一开始,请将-1
更改为-2
。
修改强>
几年过去了,我终于开始写这篇文章了。 http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/答案 3 :(得分:21)
您可以使用YEARWEEK()功能获取连锁的年份和周数(200945)。如果我正确理解您的目标,那么您应该可以对多年数据进行分组。
如果您需要本周开始时的实际时间戳,那就不太好了:
DATE_SUB( field, INTERVAL DAYOFWEEK( field ) - 1 DAY )
对于每月订购,您可能会考虑LAST_DAY()功能 - 排序将在该月的最后一天进行,但这相当于按月的第一天排序...不应该吗?< / p>
答案 4 :(得分:4)
只需在选择中添加:
DATE_FORMAT($yourDate, \'%X %V\') as week
并且
group_by(week);
答案 5 :(得分:2)
如果您需要“周结束”日期,这也可以。这将计算每周的记录数。示例:如果在(包括)1/2/2010和1/8/2010之间创建了三个工作订单,并且在(包括)2010年1月9日和2010年1月16日之间创建了5个工作订单,则返回:
3 1/8/2010
5 1/16/2010
我不得不使用额外的DATE()函数来截断我的日期时间字段。
SELECT COUNT(*), DATE_ADD( DATE(wo.date_created), INTERVAL (7 - DAYOFWEEK( wo.date_created )) DAY) week_ending
FROM work_order wo
GROUP BY week_ending;
答案 6 :(得分:0)
我喜欢 MySQL 中的 week 函数,但在我的情况下,我想知道一行在一个月的哪一周。我使用了这个解决方案:
其中 run_date
是一个时间戳,如 2021-02-25 00:00:00
concat (
date_format(run_date, '%Y-%m'),
' wk ',
(week(run_date,1) - ( week(date_format(run_date, '%Y-%m-01')) - 1))
) as formatted_date
输出:
2021-02-23 ---> 2021-02 wk 4
2021-02-25 ---> 2021-02 wk 4
2021-02-11 ---> 2021-02 wk 2
2021-03-02 ---> 2021-03 wk 1
这背后的想法是我想(相对确定地)知道该日期发生在月份的哪一周?
所以我们连接:
date_format(run_date, '%Y-%m')
得到 2021-02
然后我们添加文字字符串wk
然后我们使用:
week(run_date, 1)
获取此记录的周(1
开始星期一),(这将是 7
,因为 02/21/2021 是在一年的第 7 周,我们减去无论该月的第 1 天是哪一周 - week()
的 2021-02-01
是 5,因为它在一年中的第 5 周:
(week(date_format(run_date, '%Y-%m-01'))
不幸的是,这会从 0 开始计数,这是人们不喜欢的,所以我们从串联结果的最后一部分减去 1,这样“周”从 1 开始。
答案 7 :(得分:0)
这可能是一个不错的选择:
SELECT
year(datetime_field) as year_date, week(datetime_field) as week_date
FROM
bd.table
GROUP BY
year_date, week_date;
它看起来像这样: