如何获取给定日期范围内的星期列表?

时间:2019-12-13 07:40:37

标签: mysql

我想要周列表,其中包含周号,两个日期之间的周开始日期和结束日期。让我举一个例子,

如果我将开始日期传递为2019-12-11,将结束日期传递为2019-12-25,则预期输出应如下所示:

Week Number | Week start date | Week end date

W1           2019-12-11       2019-12-14     
W2           2019-12-15       2019-12-21     
W3           2019-12-22       2019-12-25

我尝试使用下面的查询,但是得到了

这样的输出
 Week start date | Week end date

 2019-12-15        2019-12-21     
 2019-12-22        2019-12-28     
select start_date, date_add(start_date, INTERVAL 6 DAY) as end_date
from
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) start_date
from
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where start_date between '2019-12-11' and '2019-12-25'
AND date_format(start_date, '%w') = 0

1 个答案:

答案 0 :(得分:1)

您可以使用WEEK函数和ROW_NUMBER使用以下解决方案:

-- calendar table: https://stackoverflow.com/a/45992247/3840840
SELECT CONCAT('W', ROW_NUMBER() OVER (ORDER BY WEEK(start_date))) AS `Week Number`, 
  MIN(start_date) AS `Week start date`, MAX(start_date) AS `Week end date`
FROM (
  SELECT ADDDATE('1970-01-01', t4 * 10000 + t3 * 1000 + t2 * 100 + t1 * 10 + t0) AS start_date
  FROM
    (SELECT 0 t0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
    (SELECT 0 t1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
    (SELECT 0 t2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
    (SELECT 0 t3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
    (SELECT 0 t4 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4
) v
WHERE start_date BETWEEN '2019-12-11' AND '2019-12-25'
GROUP BY WEEK(start_date)
ORDER BY WEEK(start_date)

通过使用WEEK,您不必自己计算周数。 MySQL可以检测周。使用WEEK,您可以获取日期值的星期数。您可以按本周编号分组以获取每周的行数。在日期值上使用MINMAX,您将获得每周的第一个和最后一个日期。

使用ROW_NUMBER,您可以在结果中添加行号。从MySQL 8.0开始,此功能可用。在早期版本的MySQL上,您可以使用以下解决方案:

SELECT CONCAT('W', @row_number:=@row_number+1) AS `Week Number`, 
  MIN(start_date) AS `Week start date`, MAX(start_date) AS `Week end date`
FROM (
  SELECT ADDDATE('1970-01-01', t4 * 10000 + t3 * 1000 + t2 * 100 + t1 * 10 + t0) AS start_date
  FROM
    (SELECT 0 t0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
    (SELECT 0 t1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
    (SELECT 0 t2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
    (SELECT 0 t3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
    (SELECT 0 t4 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4
  ORDER BY start_date
) v, (SELECT @row_number:=0) rn
WHERE start_date BETWEEN '2019-12-11' AND '2019-12-25'
GROUP BY WEEK(start_date)
ORDER BY WEEK(start_date)

demo on dbfiddle.uk