使用SQL(MySQL)选择每隔一周的一天

时间:2018-08-13 19:30:40

标签: mysql

目标是返回一组与请求的星期几相对应的日期。

例如:2018-08-132018-12-31之间的每隔一个星期一。

以下语句返回所有日期,效果很好

select * from 
(select adddate('2010-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) DATES 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 DATES between '2018-08-13' and '2018-12-31'
and dayname(DATES) ='MONDAY'

为了返回其他每个星期一,我添加了以下内容

HAVING DATES % 2 = 0

我假设通过对日期进行MOD,在这种情况下,它将返回每个符合此条件的星期一。好吧,它不起作用。我尝试了各种连击,但没有得到。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

日期是一个复杂的数据结构,在DBMS之间,如何存储和操作它们的细节有所不同。通常,您不能像在此处尝试的那样将它们视为数字数据类型。相反,您应该计算感兴趣的日期和固定的日期之间的天数,然后可以采用该数字的模数:例如:

select * from 
(select adddate('2010-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) DATES 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 DATES between '2018-08-13' and '2019-01-31'
and dayname(DATES) ='MONDAY'
and datediff(dates,'2018-08-13') % 2 = 0
order by dates

或者每隔一个星期一间隔14天,则可以使用模数14并删除dayname(DATES) ='MONDAY'谓词:

select * from 
(select adddate('2010-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) DATES 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 DATES between '2018-08-13' and '2019-01-31'
and datediff(dates,'2018-08-13') % 14 = 0
order by dates

答案 1 :(得分:0)

可以对它进行一些小的修改,如下所示:

SELECT * FROM
( 
SELECT ADDDARE('1970-01-01', t4*10000 + t3*1000 + t2*100 + t1*10 + t0) selected_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 
    selected_date between '2018-08-08' AND '2018-10-19'
    AND DAYOFWEEK(selected_date) = 2
    AND WEEK(selected_date) % 2 = WEEK('2018-08-08') % 2

想法是它将包括选择期开始的一周的星期一。因此,开始的星期是奇数还是偶数都没有关系,您总是会得到一个交替的星期一,而不必担心为模运算的结果指定01