在 SQL 服务器中保留今天日期的最后 n 个工作日记录
Keep last n business days records from today date in SQL Server
我们如何在这个 table:
中保留从今天开始的最后 n 个工作日的记录
Suppose n = 7
示例数据:
表 1:
Date
----------
2021-11-29
2021-11-30
2021-12-01
2021-12-02
2021-12-03
2021-12-04
2021-12-05
2021-12-06
2021-12-07
2021-12-08
2021-12-09
2021-12-10
2021-12-11
2021-12-12
2021-12-13
基于此 table 数据,我们希望输出如下所示。它应该删除 12 月 3 日之前的所有行或最近 7 个工作日的数据。
Date
-------
2021-12-03
2021-12-06
2021-12-07
2021-12-08
2021-12-09
2021-12-10
2021-12-13
注意:如果我们在工作日之间保留周六、周日的数据就可以了。
我试过这个查询
DECLARE @n INT = 7
SELECT * FROM Table1
WHERE [date] < Dateadd(day, -((@n + (@n / 5) * 2)), Getdate())
但是周六、周日的逻辑不符合我的逻辑。请提出更好的方法。
您可以使用 CTE 标记目标日期,然后从 table 中删除所有其他日期,如下所示:
; With CTE As (
Select [Date], Row_number() Over (Order by [Date] Desc) As Num
From tbl
Where DATEPART(weekday, [Date]) Not In (6,7)
)
Delete From tbl
Where [Date] Not In (Select [Date] From CTE Where Num<=7)
如果 table 中的工作日可能少于 7 天,您需要通过添加休息日使总天数达到 7 天,试试这个:
Declare @n Int = 7
; With CTE As (
Select [Date], IIF(DATEPART(weekday, [Date]) In (6,7), 0, 1) As IsBusinessDay
From tbl
)
Delete From tbl
Where [Date] Not In (Select Top(@n) [Date] From CTE Order By IsBusinessDay Desc, [Date] Desc)
如果每天只有一个日期,你可以简单地这样做:
SELECT TOP 7 [Date] FROM Table1
WHERE
[Date] < GETDATE() AND DATENAME(weekday, [DATE]) NOT IN ('Saturday', 'Sunday')
ORDER BY
[DATE] DESC
您可以得到从今天开始的第 7 个工作日作为
select top(1) cast(dateadd(d, -n + 1, getdate()) as date) d
from (
select n
, sum (case when datename(dw, dateadd(d, -n + 1, getdate())) not in ('Sunday', 'Saturday') then 1 end) over(order by n) wdn
from (
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11)
)t0(n)
) t
where wdn = 7
order by n;
通常在第@n 天使用即时计数
declare @n int = 24;
with t0(n) as (
select n
from (
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
) t(n)
), tally as (
select top(@n + (@n/5 +1)*2) row_number() over(order by t1.n) n
from t0 t1, t0 t2, t0 t3
)
select top(1) cast(dateadd(d, -n + 1, getdate()) as date) d
from (
select n
, sum (case when datename(dw, dateadd(d, -n + 1, getdate())) not in ('Sunday', 'Saturday') then 1 end) over(order by n) wdn
from tally
) t
where wdn = @n
order by n;
我们如何在这个 table:
中保留从今天开始的最后 n 个工作日的记录Suppose n = 7
示例数据:
表 1:
Date
----------
2021-11-29
2021-11-30
2021-12-01
2021-12-02
2021-12-03
2021-12-04
2021-12-05
2021-12-06
2021-12-07
2021-12-08
2021-12-09
2021-12-10
2021-12-11
2021-12-12
2021-12-13
基于此 table 数据,我们希望输出如下所示。它应该删除 12 月 3 日之前的所有行或最近 7 个工作日的数据。
Date
-------
2021-12-03
2021-12-06
2021-12-07
2021-12-08
2021-12-09
2021-12-10
2021-12-13
注意:如果我们在工作日之间保留周六、周日的数据就可以了。
我试过这个查询
DECLARE @n INT = 7
SELECT * FROM Table1
WHERE [date] < Dateadd(day, -((@n + (@n / 5) * 2)), Getdate())
但是周六、周日的逻辑不符合我的逻辑。请提出更好的方法。
您可以使用 CTE 标记目标日期,然后从 table 中删除所有其他日期,如下所示:
; With CTE As (
Select [Date], Row_number() Over (Order by [Date] Desc) As Num
From tbl
Where DATEPART(weekday, [Date]) Not In (6,7)
)
Delete From tbl
Where [Date] Not In (Select [Date] From CTE Where Num<=7)
如果 table 中的工作日可能少于 7 天,您需要通过添加休息日使总天数达到 7 天,试试这个:
Declare @n Int = 7
; With CTE As (
Select [Date], IIF(DATEPART(weekday, [Date]) In (6,7), 0, 1) As IsBusinessDay
From tbl
)
Delete From tbl
Where [Date] Not In (Select Top(@n) [Date] From CTE Order By IsBusinessDay Desc, [Date] Desc)
如果每天只有一个日期,你可以简单地这样做:
SELECT TOP 7 [Date] FROM Table1
WHERE
[Date] < GETDATE() AND DATENAME(weekday, [DATE]) NOT IN ('Saturday', 'Sunday')
ORDER BY
[DATE] DESC
您可以得到从今天开始的第 7 个工作日作为
select top(1) cast(dateadd(d, -n + 1, getdate()) as date) d
from (
select n
, sum (case when datename(dw, dateadd(d, -n + 1, getdate())) not in ('Sunday', 'Saturday') then 1 end) over(order by n) wdn
from (
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11)
)t0(n)
) t
where wdn = 7
order by n;
通常在第@n 天使用即时计数
declare @n int = 24;
with t0(n) as (
select n
from (
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
) t(n)
), tally as (
select top(@n + (@n/5 +1)*2) row_number() over(order by t1.n) n
from t0 t1, t0 t2, t0 t3
)
select top(1) cast(dateadd(d, -n + 1, getdate()) as date) d
from (
select n
, sum (case when datename(dw, dateadd(d, -n + 1, getdate())) not in ('Sunday', 'Saturday') then 1 end) over(order by n) wdn
from tally
) t
where wdn = @n
order by n;