如何选择一年中的每个星期一和每个星期五的日期

时间:2014-09-28 19:34:30

标签: sql sql-server-2012

基本上我希望能够选择一年中每周的星期一和星期五。

所以例如本周即将到来的我想要2014年9月29日和2014年10月3日,但我希望这一年中的每一周。

2 个答案:

答案 0 :(得分:2)

您可以使用带有数字的合适表格,例如master..spt_values表作为范围生成的基础:

;WITH dates AS (
    SELECT DATEADD(DAY,number,CAST('2014-01-01' AS DATE)) d
    FROM master..spt_values WHERE TYPE = 'p'
    AND number < 366
    )

SELECT 
    Week = DATEPART(WEEK, d), 
    DayOfWeek = DATENAME(dw, d), 
    Date = d
FROM dates
WHERE DATENAME(dw, d) IN ('Monday', 'Friday')
-- or use datepart instead as datename might be specific to language
-- WHERE DATEPART(dw, d) IN (2,6)

示例输出:

Week        DayOfWeek                      Date
----------- ------------------------------ ----------
1           Friday                         2014-01-03
2           Monday                         2014-01-06
2           Friday                         2014-01-10
3           Monday                         2014-01-13
3           Friday                         2014-01-17
4           Monday                         2014-01-20
4           Friday                         2014-01-24
5           Monday                         2014-01-27
5           Friday                         2014-01-31

答案 1 :(得分:1)

这是一种方式(您可能需要检查一周中的哪一天设置为第一天,这里我将周日作为一周的第一天)

您可以使用包含许多行(超过365个)到CROSS JOIN的表来获取一系列日期(计数表)。

我的sys列有超过800行,你可以使用任何其他表,甚至CROSS JOIN表自己来增加行数

在这里,我使用row_number函数获取行的运行计数,并将每行的日期递增1天:

select 
dateadd(d, row_number() over (order by name), cast('31 Dec 2013' as datetime)) as dt 
from sys.columns a

现在使用结果日期设置,使用datepart()

检查星期几是微不足道的
SELECT
    dt, 
    datename(dw, dt) 
FROM 
    (
        select 
            dateadd(d, row_number() over (order by name), cast('31 Dec 2013' as datetime)) as dt 
            from 
            sys.columns a
    ) as dates 
WHERE 
(datepart(dw, dates.dt) = 2 OR datepart(dw, dates.dt) = 6)
AND dt >= '01 Jan 2014' AND dt < '01 Jan 2015'

编辑:

这是一个SqlFiddle的例子

http://sqlfiddle.com/#!6/d41d8/21757

编辑2:

如果你想要他们在同一行,一周中的几天至少是不变的,你知道周五总是在星期一后4天所以做同样的但只看星期一,然后只需要在星期一加4天。

SELECT
    dt as MonDate, 
    datename(dw, dt) as MonDateName,
    dateadd(d, 4, dt) as FriDate,
    datename(dw, dateadd(d, 4, dt)) as FriDateName
FROM 
    (
        select 
            dateadd(d, row_number() over (order by name), cast('31 Dec 2013' as datetime)) as dt 
            from 
            sys.columns a
    ) as dates 
WHERE 
datepart(dw, dates.dt) = 2
AND dt >= '01 Jan 2014' AND dt < '01 Jan 2015'
AND dt >= '01 Jan 2014' AND dt < '01 Jan 2015'

示例SqlFiddle:

http://sqlfiddle.com/#!6/d41d8/21764

(请注意,由于sys.columns在SqlFiddle服务器上很小,所以只返回几行,如果这是一个问题,请尝试另一个系统表)