我可以找到特定月份的星期六和星期日的某一天的日期吗?例如,考虑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
语句中完成它
答案 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'你只需要弄清楚如何生成一个月/一年的所有日期?