如何在SQL Server中仅获取当前周的数据?

31

我想从存储插入记录的表中获取当前一周内插入的记录。

我尝试过:

SELECT PId 
,WorkDate 
,Hours          
,EmpId            
FROM Acb       
WHERE EmpId=@EmpId AND WorkDate BETWEEN DATEADD(DAY, -7, GETDATE()) AND GETDATE()

1
你的查询出了什么问题? - shree.pat18
它显示从今天日期到过去7天的记录。@shree.pat18 - sona
定义“本周”。它是从星期日还是星期一开始的? - Greenstone Walker
尝试改为-6。 - shree.pat18
本周从星期一开始@Greenstone Walker - sona
7个回答

47

就这样做:

SET DATEFIRST 1 -- Define beginning of week as Monday
SELECT [...]
AND WorkDate >= dateadd(day, 1-datepart(dw, getdate()), CONVERT(date,getdate())) 
AND WorkDate <  dateadd(day, 8-datepart(dw, getdate()), CONVERT(date,getdate()))

说明:

  • datepart(dw, getdate()) 返回当前周的日期数字,从1到7,以您使用 SET DATEFIRST 指定的日期开始计算。
  • dateadd(day, 1-datepart(dw, getdate()), getdate()) 减去必要的天数以到达当前周的开始位置。
  • CONVERT(date,getdate()) 用于删除 GETDATE() 的时间部分,因为您想要从午夜开始的数据。

非常感谢您的回答。它完美地解决了我的问题。再次感谢。@Twinkles - sona
如果我想使用自己的日期对象而不是预定义的getdate(),我该怎么做? - Minasie Shibeshi
非常感谢。需要注意的是,在存储过程调用后,SET DATEFIRST 1 会恢复到其原始状态。 - orBeat

11
更好的方式是:
select datepart(ww, getdate()) as CurrentWeek

你也可以使用wk而不是ww。

Datepart文档


2
我知道这是老的(只是通过谷歌发现),但这是否也会返回在同一周内,但来自不同年份的记录? - 3N1GM4
重复的答案 - 回答于2014年4月14日12:53,Amul Harad - AquaAlex
@AquaAlex,它们不是重复的。 - Henrik Erlandsson
请注意,例如2019-12-31和2020-01-01在同一周的第一周,但是datepart(ww, getdate())将返回53和1。 - Nerdroid

2

它对我有效。

Select * From Acb Where WorkDate BETWEEN DATEADD(DAY, -7, GETDATE()) AND DATEADD(DAY, 1, GETDATE())

你需要在AND子句后添加以下代码:AND DATEADD(DAY, 1, GETDATE())


您检索的数据不是本周的,而是一周前的数据。 - AquaAlex

1

datepart(dw, getdate()) 是本周的当前日期,dateadd(day, 1-datepart(dw, getdate()), getdate()) 应该是本周的第一天,加上7即可得到本周的最后一天。


0

您可以使用以下查询来提取当前周:

select datepart(dw, getdate()) as CurrentWeek

这不是返回当前星期几,而不是当前年份的周数吗? - 3N1GM4

0

使用DATEDIFF也可以,但有点hacky,因为它不关心datefirst

set datefirst 1; -- set monday as first day of week
declare @Now datetime = '2020-09-28 11:00';


select * 
into #Temp
from
(select 1 as Nbr, '2020-09-22 10:00' as Created
union
select 2 as Nbr, '2020-09-25 10:00' as Created
union
select 2 as Nbr, '2020-09-28 10:00' as Created) t


select * from #Temp where DATEDIFF(ww, dateadd(dd, -@@datefirst, Created), dateadd(dd, -@@datefirst, @Now)) = 0 -- returns 1 result
select * from #Temp where DATEDIFF(ww, dateadd(dd, -@@datefirst, Created), dateadd(dd, -@@datefirst, @Now)) = 1 -- returns 2 results


drop table #Temp

0
SET DATEFIRST 1;
    ;With CTE
    AS
    (
    SELECT
    FORMAT(CreatedDate, 'MMMM-yyyy') as Months,
    CASE 
    WHEN YEAR(DATEADD(DAY, 1-DATEPART(WEEKDAY, Min(CreatedDate)), Min(CreatedDate))) < YEAR(Min(CreatedDate))
    THEN FORMAT(DATEADD(YEAR, DATEDIFF(YEAR, 0,DATEADD(YEAR, 0 ,GETDATE())), 0) ,'MMM dd')   + ' - ' + FORMAT(DATEADD(dd, 7-(DATEPART(dw, Min(CreatedDate))), Min(CreatedDate))  ,'MMM dd')
    ELSE
    FORMAT(DATEADD(DAY, 1-DATEPART(WEEKDAY, Min(CreatedDate)), Min(CreatedDate)) ,'MMM dd') + ' - ' + FORMAT(DATEADD(dd, 7-(DATEPART(dw, Min(CreatedDate))), Min(CreatedDate)) ,'MMM dd') 
    END  DateRange,
    Sum(ISNULL(Total,0)) AS Total,
    sum(cast(Duration as int)) as   Duration    
    FROM TL_VriandOPI_Vendorbilling where VendorId=@userID and CompanyId=@CompanyID
    Group By DATEPART(wk, CreatedDate) ,FORMAT(CreatedDate, 'MMMM-yyyy')
    )
    SELECT Months,DateRange,Total,Duration,
    case when DateRange=(select FORMAT(DATEADD(DAY, 1-DATEPART(WEEKDAY, Min(getdate())), Min(getdate())) ,'MMM dd') + ' - ' +
    FORMAT(DATEADD(dd, 7-(DATEPART(dw, Min(getdate()))), Min(getdate())) ,'MMM dd'))
    then 1 else 0 end as Thisweek
    FROM CTE order by Months desc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接