我试图比较几个月的数据,但数据是特定日期的,所以我需要比较6月的第1个星期一和7月的第1个星期一,然后是第1个星期二,依此类推。我将在下面回答我使用的查询,但想知道查询是否具有远程效率或是否有更好的方法。此外,我还希望从局外人那里快速进行逻辑检查,以确保查询能够按照我打算在所有情况下的方式运行。
对于令人费解的标题表示道歉希望一旦你看到这个问题就会更有意义,如果有任何编辑想要更清晰的标题,请提出建议。
查询:
select
[start time],
case
when DATEPART(DW,[start time]) = 1 and DATEPART(dd,[Start Time]) < 8 then '1st Sunday'
when DATEPART(DW,[start time]) = 1 and DATEPART(dd,[Start Time]) > 7 and DATEPART(dd,[Start Time]) < 16 then '2nd Sunday'
when DATEPART(DW,[start time]) = 1 and DATEPART(dd,[Start Time]) > 15 and DATEPART(dd,[Start Time]) < 24 then '3rd Sunday'
when DATEPART(DW,[start time]) = 1 and DATEPART(dd,[Start Time]) > 23 and DATEPART(dd,[Start Time]) < 31 then '4th Sunday'
when DATEPART(DW,[start time]) = 1 and DATEPART(dd,[Start Time]) > 30 and DATEPART(dd,[Start Time]) < 32 then '5th Sunday'
when DATEPART(DW,[start time]) = 2 and DATEPART(dd,[Start Time]) < 8 then '1st Monday'
when DATEPART(DW,[start time]) = 2 and DATEPART(dd,[Start Time]) > 7 and DATEPART(dd,[Start Time]) < 16 then '2nd Monday'
when DATEPART(DW,[start time]) = 2 and DATEPART(dd,[Start Time]) > 15 and DATEPART(dd,[Start Time]) < 24 then '3rd Monday'
when DATEPART(DW,[start time]) = 2 and DATEPART(dd,[Start Time]) > 23 and DATEPART(dd,[Start Time]) < 31 then '4th Monday'
when DATEPART(DW,[start time]) = 2 and DATEPART(dd,[Start Time]) > 30 and DATEPART(dd,[Start Time]) < 32 then '5th Monday'
when DATEPART(DW,[start time]) = 3 and DATEPART(dd,[Start Time]) < 8 then '1st Tuesday'
when DATEPART(DW,[start time]) = 3 and DATEPART(dd,[Start Time]) > 7 and DATEPART(dd,[Start Time]) < 16 then '2nd Tuesday'
when DATEPART(DW,[start time]) = 3 and DATEPART(dd,[Start Time]) > 15 and DATEPART(dd,[Start Time]) < 24 then '3rd Tuesday'
when DATEPART(DW,[start time]) = 3 and DATEPART(dd,[Start Time]) > 23 and DATEPART(dd,[Start Time]) < 31 then '4th Tuesday'
when DATEPART(DW,[start time]) = 3 and DATEPART(dd,[Start Time]) > 30 and DATEPART(dd,[Start Time]) < 32 then '5th Tuesday'
when DATEPART(DW,[start time]) = 4 and DATEPART(dd,[Start Time]) < 8 then '1st Wednesday'
when DATEPART(DW,[start time]) = 4 and DATEPART(dd,[Start Time]) > 7 and DATEPART(dd,[Start Time]) < 16 then '2nd Wednesday'
when DATEPART(DW,[start time]) = 4 and DATEPART(dd,[Start Time]) > 15 and DATEPART(dd,[Start Time]) < 24 then '3rd Wednesday'
when DATEPART(DW,[start time]) = 4 and DATEPART(dd,[Start Time]) > 23 and DATEPART(dd,[Start Time]) < 31 then '4th Wednesday'
when DATEPART(DW,[start time]) = 4 and DATEPART(dd,[Start Time]) > 30 and DATEPART(dd,[Start Time]) < 32 then '5th Wednesday'
when DATEPART(DW,[start time]) = 5 and DATEPART(dd,[Start Time]) < 8 then '1st Thursday'
when DATEPART(DW,[start time]) = 5 and DATEPART(dd,[Start Time]) > 7 and DATEPART(dd,[Start Time]) < 16 then '2nd Thursday'
when DATEPART(DW,[start time]) = 5 and DATEPART(dd,[Start Time]) > 15 and DATEPART(dd,[Start Time]) < 24 then '3rd Thursday'
when DATEPART(DW,[start time]) = 5 and DATEPART(dd,[Start Time]) > 23 and DATEPART(dd,[Start Time]) < 31 then '4th Thursday'
when DATEPART(DW,[start time]) = 5 and DATEPART(dd,[Start Time]) > 30 and DATEPART(dd,[Start Time]) < 32 then '5th Thursday'
when DATEPART(DW,[start time]) = 6 and DATEPART(dd,[Start Time]) < 8 then '1st Friday'
when DATEPART(DW,[start time]) = 6 and DATEPART(dd,[Start Time]) > 7 and DATEPART(dd,[Start Time]) < 16 then '2nd Friday'
when DATEPART(DW,[start time]) = 6 and DATEPART(dd,[Start Time]) > 15 and DATEPART(dd,[Start Time]) < 24 then '3rd Friday'
when DATEPART(DW,[start time]) = 6 and DATEPART(dd,[Start Time]) > 23 and DATEPART(dd,[Start Time]) < 31 then '4th Friday'
when DATEPART(DW,[start time]) = 6 and DATEPART(dd,[Start Time]) > 30 and DATEPART(dd,[Start Time]) < 32 then '5th Friday'
when DATEPART(DW,[start time]) = 7 and DATEPART(dd,[Start Time]) < 8 then '1st Saturday'
when DATEPART(DW,[start time]) = 7 and DATEPART(dd,[Start Time]) > 7 and DATEPART(dd,[Start Time]) < 16 then '2nd Saturday'
when DATEPART(DW,[start time]) = 7 and DATEPART(dd,[Start Time]) > 15 and DATEPART(dd,[Start Time]) < 24 then '3rd Saturday'
when DATEPART(DW,[start time]) = 7 and DATEPART(dd,[Start Time]) > 23 and DATEPART(dd,[Start Time]) < 31 then '4th Saturday'
when DATEPART(DW,[start time]) = 7 and DATEPART(dd,[Start Time]) > 30 and DATEPART(dd,[Start Time]) < 32 then '5th Saturday'
else 'Other' end as [day]
from inboundcallsview
答案 0 :(得分:0)
最简单的方法是用非常少的指令来完成这个。在这个我会选择Calendar table。我可以填充一次,占用一些硬盘空间就可以了..
我们可以用它来完成各种任务..
来到你的榜样,如果我们想知道多年来的星期五,我们可以简单地查询如下
答案 1 :(得分:0)
您可以使用日历表:
DECLARE @dateStart date = '2016-01-01',
@dateFinish date = '2016-12-31'
;WITH dates as (
SELECT CAST(@dateStart as datetime) d
UNION ALL
SELECT DATEADD(day,1,d)
FROM dates
WHERE d < @dateFinish
), cte AS (
SELECT CAST(d as date) as D,
ROW_NUMBER() OVER (PARTITION BY MONTH(d),DATENAME(WEEKDAY,d) ORDER BY d) as seq
FROM dates)
SELECT *
FROM cte
OPTION(MAXRECURSION 0)
F.e。你需要将所有第一个星期一添加到SELECT FROM cte:
的WHERE语句WHERE DATEPART(WEEKDAY,D) = 2 AND seq = 1
那会给你:
D seq
2016-01-04 1
2016-02-01 1
2016-03-07 1
2016-04-04 1
2016-05-02 1
2016-06-06 1
2016-07-04 1
2016-08-01 1
2016-09-05 1
2016-10-03 1
2016-11-07 1
2016-12-05 1
答案 2 :(得分:0)
DECLARE @DAT as datetime;
DECLARE @SUFFIX as nvarchar(50) = 'stndrdthththth';
SET @DAT = '20160801';
while @dat < '20170101'
BEGIN
SELECT @dat,
CAST((DATEPART(d,@DAT) - 1) / 7 + 1 as nvarchar(1))
+ SUBSTRING(@SUFFIX,1 + 2*(FLOOR(DATEPART(d,@DAT) - 1) / 7),2)
+ ' '
+ DATENAME(dw,@DAT);
SET @dat = @dat + 1
END
您的查询将变为
select
[start time],
CAST((DATEPART(d,@start time) - 1) / 7 + 1 as nvarchar(1))
+ SUBSTRING('stndrdthththth',1 + 2*(FLOOR(DATEPART(d,@start time) - 1) / 7),2)
+ ' '
+ DATENAME(dw,@start time) as [DAY]
from inboundcallsview
答案 3 :(得分:0)
通过定义函数,您可以使代码更具可读性:
CREATE FUNCTION [dbo].[OrdinalDate]
(
@date DATETIME
)
RETURNS int
AS
-- Returns n if @date is the nth occcurence of that weekday in the month
BEGIN
IF DATEPART(dd,@date) <= 7 THEN RETURN 1
ELSE IF DATEPART(dd,@date) > 7 and DATEPART(dd,@date) <= 15 THEN RETURN 2
[...]
END;
GO
然后你可以这样比较:
SELECT [...]
FROM table t1
INNER JOIN table t2
ON DATEPART(DW,t1.[start time]) = DATEPART(DW,t2.[start time])
AND OrdinalDate(t1.[start time]) = OrdinalDate(t2.[start time])
答案 4 :(得分:0)
你可以简单地使用它来获取周列表,
SELECT CAST(DATEDIFF(WEEK,DATEADD(mm,DATEDIFF(mm,0,[start time]),0),[start time]) +1 AS VARCHAR(2) ) + ' ' + DATENAME(WEEKDAY,[start time])
如果在周数后需要后缀,
SELECT CASE
WHEN DATEDIFF(WEEK,DATEADD(mm,DATEDIFF(mm,0,[start time]),0),[start time]) +1 = 1 THEN '1st '
WHEN DATEDIFF(WEEK,DATEADD(mm,DATEDIFF(mm,0,[start time]),0),[start time]) +1 = 2 THEN '2nd '
WHEN DATEDIFF(WEEK,DATEADD(mm,DATEDIFF(mm,0,[start time]),0),[start time]) +1 = 3 THEN '3rd '
WHEN DATEDIFF(WEEK,DATEADD(mm,DATEDIFF(mm,0,[start time]),0),[start time]) +1 = 4 THEN '4th '
WHEN DATEDIFF(WEEK,DATEADD(mm,DATEDIFF(mm,0,[start time]),0),[start time]) +1 = 5 THEN '5th '
END
+ DATENAME(WEEKDAY,[start time])
答案 5 :(得分:0)
Select
Case
WHEN CurrentMonth.WeekNum = 1 then Cast(CurrentMonth.WeekNum as nvarchar(1)) + 'st'
WHEN CurrentMonth.WeekNum = 2 then Cast(CurrentMonth.WeekNum as nvarchar(1)) +'nd'
WHEN CurrentMonth.WeekNum = 3 then Cast(CurrentMonth.WeekNum as nvarchar(1)) +'rd'
WHEN CurrentMonth.WeekNum > 3 then Cast(CurrentMonth.WeekNum as nvarchar(1)) +'th'
END,
DATENAME(dw, [start time])
from inboundcallsview
Cross Apply (Select (DATEPART(WEEK, [start time]) - DATEPART(WEEK, DATEADD(MM, DATEDIFF(MM,0,[start time]), 0))+ 1) WeekNum) AS CurrentMonth