在SQL Server中仅获取月份的星期六和星期日日期

时间:2017-03-02 11:34:42

标签: sql-server

我可以找到特定月份的星期六和星期日的某一天的日期吗?例如,考虑2017年1月的月份。以下日期是周末:

 7/1/2017 - Saturday
14/1/2017 - Saturday
21/1/2017 - Saturday
28/1/2017 - Saturday 
 1/1/2017 - Sunday
 8/1/2017 - Sunday    
15/1/2017 - Sunday
22/1/2017 - Sunday
29/1/2017 - Sunday

我想要一个SQL Server查询,这样当我将月份和年份作为输入传递时,我应该将所有上述日期(仅周六和周日的日期)作为输出返回

我不希望使用任何用户定义的函数,并希望在单个SELECT语句中完成它

7 个答案:

答案 0 :(得分:3)

注意:正如评论中其他用户已经注意到的,此查询取决于您的服务器设置,即DATEFIRST。如果您因为不同的设置需要更改查询,请告诉我,我可以为您更改它。

使用CTE作为虚拟数据......

/* Ignore this part...*/
WITH CTE AS
(
    SELECT CAST('01/01/2017' AS DATE) AS [Date]
        UNION ALL
    SELECT DATEADD(DAY,1,[Date])
    FROM CTE
    WHERE DATE <= '12/31/2017'
)
/*Your actual SELECT statement would look like this, from your own table of course*/
SELECT 
     [Date]
    ,CASE DATEPART(dw,[Date])
        WHEN 1 THEN 'Sunday'
        WHEN 2 THEN 'Monday'
        WHEN 3 THEN 'Tuesday'
        WHEN 4 THEN 'Wednesday'
        WHEN 5 THEN 'Thursday'
        WHEN 6 THEN 'Friday'
        WHEN 7 THEN 'Saturday'
    END
FROM CTE
WHERE DATEPART(dw,[Date]) IN (1,7)
AND MONTH([Date]) = 12--<month>
AND YEAR([Date]) = 2017--<year>
OPTION (MAXRECURSION 0) -- You won't need this line if you're querying a real table
;

如果运行适合您,那么您的真实查询可能如下所示:

SELECT 
     [Date]
    ,CASE DATEPART(dw,[Date])
        WHEN 1 THEN 'Sunday'
        WHEN 2 THEN 'Monday'
        WHEN 3 THEN 'Tuesday'
        WHEN 4 THEN 'Wednesday'
        WHEN 5 THEN 'Thursday'
        WHEN 6 THEN 'Friday'
        WHEN 7 THEN 'Saturday'
    END
FROM < the table you want >
WHERE DATEPART(dw,[Date]) IN (1,7) -- Only Sundays and Saturdays
AND MONTH([Date]) = < the month you want >
AND YEAR([Date]) = < the year you want >
;

如果您想生成数据,那么CTE就是您的选择。如果你传递参数,它看起来像这样:

DECLARE
     @MONTH INT
    ,@YEAR INT
;

SET @MONTH = 1;
SET @YEAR = 2017;

WITH CTE AS
(
    SELECT CAST(CAST(@MONTH AS VARCHAR(2)) + '/01/' + CAST(@YEAR AS VARCHAR(4)) AS [Date]) AS DATE
        UNION ALL
    SELECT DATEADD(DAY,1,[Date])
    FROM CTE
    WHERE DATE <= CAST(@MONTH AS VARCHAR(2)) + 
        CASE 
            WHEN @MONTH IN (9,4,6,11) 
                THEN '/30/'
            WHEN @MONTH IN (1,3,5,7,8,10,12) 
                THEN '/31/'
            WHEN @MONTH = 2 AND @YEAR/4.00 = @YEAR/4 
                THEN '/29/'
            ELSE '/28/'
        END
        + CAST(@YEAR AS VARCHAR(4))
)
SELECT 
     [Date]
    ,CASE DATEPART(dw,[Date])
        WHEN 1 THEN 'Sunday'
        WHEN 2 THEN 'Monday'
        WHEN 3 THEN 'Tuesday'
        WHEN 4 THEN 'Wednesday'
        WHEN 5 THEN 'Thursday'
        WHEN 6 THEN 'Friday'
        WHEN 7 THEN 'Saturday'
    END
FROM CTE
WHERE DATEPART(dw,[Date]) IN (1,7)
OPTION (MAXRECURSION 0)
;

答案 1 :(得分:0)

请试试这个。

DECLARE @Year AS INT=2017,
@Month AS INT=3,
@FirstDateOfYear DATETIME,
@LastDateOfYear DATETIME

SELECT @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0)
SELECT @LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0)
-- Creating Query to Prepare Year Data
;WITH cte AS (
SELECT 1 AS DayID,
@FirstDateOfYear AS FromDate,
DATENAME(dw, @FirstDateOfYear) AS Dayname
UNION ALL
SELECT cte.DayID + 1 AS DayID,
DATEADD(d, 1 ,cte.FromDate),
DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname
FROM cte
WHERE DATEADD(d,1,cte.FromDate) < @LastDateOfYear
)
SELECT FromDate AS Date, Dayname
FROM CTE
WHERE DayName IN ('Saturday','Sunday') and month(FromDate) = @Month 
OPTION (MaxRecursion 370)

答案 2 :(得分:0)

这应该可以解决问题:

DECLARE @month date = '2017-01-01'

SET @month = dateadd(month, datediff(month, 0, @month), 0)

;WITH CTE as
(
  SELECT 0 x
  FROM (values(1),(1),(1),(1),(1),(1)) x(n)
),
CTE2 as
(
  SELECT 
    top(day(eomonth(@month))) 
    -- use this syntax for sqlserver 2008
    -- top(datediff(d, @month,dateadd(month,1,@month))) 
    cast(dateadd(d, row_number()over(order by(select 1))-1,@month) as date) cDate
  FROM CTE CROSS JOIN CTE C2
)
SELECT
  cDate, 
  datename(weekday, cDate) Weekday
FROM CTE2
WHERE 
  datediff(d,0,cDate)%7 > 4

<强> Fiddle

答案 3 :(得分:0)

https://www.sqlservercentral.com/articles/finding-the-correct-weekday-regardless-of-datefirst中,您只需:

(DATEPART(dw,@您的日期)+ @@ DATEFIRST)%7不在2和6之间

答案 4 :(得分:0)

根据要求,单个select,语言中立,dateFirst中立,几乎SQL版本中立:

declare @OneDate datetime = '28/01/2017'; -- Any date from the target month/year

select MyDate -- raw date or ...
    -- convert(varchar, MyDate, 103) + ' - ' + dateName(dw, MyDate) -- as Sample
    as WeekEndDate
from (
    select dateAdd(dd, number, dateAdd(mm, dateDiff(mm, 0, @OneDate), 0)) as MyDate
    from master..spt_values
    where type = 'P' and number < 31
    ) j
where 1 + (datePart(dw, MyDate) + @@DATEFIRST + 5) % 7 in (6, 7)
    and month(MyDate) = month(@OneDate)
-- order by 1 + (datePart(dw, MyDate) + @@DATEFIRST + 5) % 7, MyDate -- as Sample
;

答案 5 :(得分:0)

另一种解决此问题的方法如下 -

DECLARE @MONTH INT,@YEAR INT
SET @MONTH = 1;
SET @YEAR = 2017;

Declare @StartDate date =CAST(CAST(@MONTH AS VARCHAR(2)) + '/01/' + CAST(@YEAR AS VARCHAR(4)) AS [Date]), @EndDate date
Set @EndDate = EOMONTH(@StartDate)

Declare @Temp table (DateOfDay date, DaysName varchar(50))
While(@StartDate <= @EndDate)
Begin

    Insert into @Temp
    SELECT  @StartDate DateOfMonth, 
            case when DATENAME(DW, @StartDate) = 'Saturday' then DATENAME(DW, @StartDate) 
                 when DATENAME(DW, @StartDate) = 'Sunday' then DATENAME(DW, @StartDate) 
            end DaysName

    set @StartDate = DATEADD(d,1,@StartDate)
End

select * from @Temp where DaysName is not null order by DaysName, DateOfDay

答案 6 :(得分:-1)

你不能做这样的事吗?

SELECT DATENAME(dw,'10/11/2016') AS DATE 
WHERE DATE CONTAINS('Saturday') OR DATE CONTAINS('SUNDAY')

而不是'10 / 11/2016'你只需要弄清楚如何生成一个月/一年的所有日期?