Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何在一个月内获得所有的星期一?_Mysql - Fatal编程技术网

Mysql 如何在一个月内获得所有的星期一?

Mysql 如何在一个月内获得所有的星期一?,mysql,Mysql,我想在2015年5月获得所有的周一 (使用mysql查询) 输出: MON 04 11 18 25 输出 +------------+ | Mon | +------------+ | 4 | | 11 | | 18 | | 25 | +------------+ 稍微调整一下这个这个查询返回一个月内星期一的两位数日值 这需要“月”作为该月第一天的日期,作为第一个内联视图(d0)的选择列表中的值

我想在2015年5月获得所有的周一

(使用mysql查询)

输出:

MON   
04  
11  
18  
25
输出

+------------+
| Mon        |
+------------+
|          4 |
|         11 |
|         18 |
|         25 |
+------------+

稍微调整一下这个

这个查询返回一个月内星期一的两位数日值

这需要“月”作为该月第一天的日期,作为第一个内联视图(d0)的选择列表中的值。(可以调整此内联视图查询,将一个月内的任何日期值作为一个月的规范来处理。)


作为参考,这里有另一个解决方案-请注意,最后一个条目可能为null,必要时可以更改为另一个值,或者在非null上使用子选择和筛选

SET @date='2015-05-01';
SET @offset=7 - WeekDay(@date);

SELECT DAY(DATE_ADD(@date,INTERVAL @offset DAY)) AS 'MON'
UNION SELECT DAY(DATE_ADD(@date,INTERVAL @offset+7 DAY))
UNION SELECT DAY(DATE_ADD(@date,INTERVAL @offset+14 DAY))
UNION SELECT DAY(DATE_ADD(@date,INTERVAL @offset+21 DAY))
UNION DISTINCT SELECT IF(DAY(DATE_ADD(@date,INTERVAL @offset+28 DAY))>21,
            DAY(DATE_ADD(@date,INTERVAL @offset+28 DAY)),
            DAY(DATE_ADD(@date,INTERVAL @offset+21 DAY)))
;

SQL Fiddle:

作为旁白,对于更长期、更具可扩展性的解决方案,请查看日历表;很好
7-WEEKDAY()
获取到达下一个星期一需要提前的天数。可以对查询进行调整,以避免在不包含第五个星期一的月份内返回额外的空行。由于查询使用的是
UNION
,因此我们可以使用为其他行之一返回的表达式替换
NULL
;联合集操作符将删除重复项。这是真的,我想知道
UNION DISTINCT
-更新的查询作为响应。
UNION
后面不需要
DISTINCT
关键字。
联合
隐式地是一个
联合
。当我们指定
UNION ALL
时,我们只会得到不同的行为。
UNION ALL
不会执行删除重复项的操作,这就是为什么这通常比
UNION
快。我认为当
@date
本身是星期一时,此查询不会返回正确的结果。看起来查询跳过了这个步骤,并返回下一个星期一。
SELECT DATE_FORMAT(d0.dt + INTERVAL d1.i*6+d2.i DAY,'%d')   AS dd
 --  , d0.dt + INTERVAL d1.i*6+d2.i DAY                     AS dt
  FROM ( SELECT '2015-05-01' + INTERVAL 0 DAY AS dt 
       ) d0
 CROSS
  JOIN ( SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5
       ) d1
 CROSS
  JOIN ( SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5
       ) d2
 WHERE d0.dt + INTERVAL d1.i*6+d2.i DAY < d0.dt + INTERVAL 1 MONTH
   AND NOT WEEKDAY(d0.dt + INTERVAL d1.i*6+d2.i DAY)
 ORDER BY 1
dd
--
04
11
18
25
SET @date='2015-05-01';
SET @offset=7 - WeekDay(@date);

SELECT DAY(DATE_ADD(@date,INTERVAL @offset DAY)) AS 'MON'
UNION SELECT DAY(DATE_ADD(@date,INTERVAL @offset+7 DAY))
UNION SELECT DAY(DATE_ADD(@date,INTERVAL @offset+14 DAY))
UNION SELECT DAY(DATE_ADD(@date,INTERVAL @offset+21 DAY))
UNION DISTINCT SELECT IF(DAY(DATE_ADD(@date,INTERVAL @offset+28 DAY))>21,
            DAY(DATE_ADD(@date,INTERVAL @offset+28 DAY)),
            DAY(DATE_ADD(@date,INTERVAL @offset+21 DAY)))
;