2015-12-11 21 views
5

In-để có được tất cả các Sunday datesSaturday dates giữa trao date ranges Tôi đã sử dụng một iterative solution như dưới đây,Nhận ngày cụ thể giữa cho ngày-ranges sử dụng bộ tiếp cận dựa trên

create TABLE #Dayweeks (id int IDENTITY(1,1),StartWeek DATETIME, EndWeek DATETIME) 

DECLARE @wkstartdate datetime = '2015-12-06', 
     @wkenddate datetime = '2016-04-05' 



WHILE (@wkstartdate <= @wkenddate) 
    BEGIN 
     INSERT INTO #Dayweeks 
     (
     StartWeek, EndWeek 
     ) 
     SELECT 
     @wkstartdate, DATEADD(wk,DATEDIFF(wk,0,@wkstartdate),6)-1 

     SELECT @wkstartdate = DATEADD(dd,7,@wkstartdate) 
    END 

Tôi tự hỏi làm thế nào để đạt được điều này sử dụng set based approach. Có cách nào để nhận kết quả ở trên bằng cách sử dụng set based approach không?

Kết quả tôi nhận được bằng cách sử dụng giải pháp lặp được đưa ra dưới đây.

enter image description here

Trả lời

1

Kiểm tra này với CTE:

Declare @DateFrom DateTime ='2011-07-01', 
      @DateTo DateTime = '2011-07-31' 
;WITH CTE(dt) 
AS 
(
     Select @DateFrom 
     Union All 
     Select DATEADD(d,1,dt)FROM CTE 
     Where dt<@DateTo 
) 
Select 
    DATENAME(dw,dt) day, dt 
from CTE 
where DATENAME(dw,dt)In('Sunday' , 'Saturday') 

--To understand more, comment above select and run this. 
select * from 
(
    select 'Sunday' day,dt from CTE 
    where DATENAME(dw,dt)In('Sunday') 
    union 
    select 'Saturday',dt from CTE 
    where DATENAME(dw,dt)In('Saturday') 

) a order by dt 

Kiểm tra link này để hiểu cả hai cách tiếp cận.

+0

nó trả Bảy và Chủ Nhật như hàng trong một cột duy nhất . Tôi cần Thứ Bảy và Chủ Nhật là các cột khác nhau. cảm ơn – bmsqldev

2

Thật sự không có cách tiếp cận "thiết lập dựa trên" khi được bắt đầu với một tập rỗng. Bạn có thể thay thế mã của mình bằng CTE đệ quy. Bạn có thể có được ngày bắt đầu bằng cách thực hiện:

with weeks as (
     select @wkstartdate as dte 
     union all 
     select dateadd(weeks, 1, dte) 
     from dte 
     where dte < @wkenddate 
) 
insert into #Dayweeks(Startweek, EndWeek) 
    select dte, dateadd(day, 6, dte) 
    from weeks 
option (maxrecursion 0); 

Lưu ý rằng điều này không xác minh yêu cầu trong ngày trong tuần. Nó chỉ đếm tuần từ ngày đầu tiên.

2

này nên giải quyết nó bằng cách sử dụng bảng kiểm đếm:

DECLARE @wkstartdate datetime = '2015-12-06', 
     @wkenddate datetime = '2016-04-05' 

;WITH N(N)AS 
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)), 
tally(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a,N b,N c,N d,N e,N f) 
, alldays as 
(
    SELECT 
    top (datediff(d, @wkstartdate, @wkenddate)) 
     cast(dateadd(d, N-1, @wkstartdate) as date) day 
    FROM tally 
) 
SELECT day 
FROM alldays 
WHERE datediff(d, 0, day) % 7 in(5,6) 

EDIT Phiên bản cải tiến:

DECLARE @wkstartdate datetime = '2015-12-06', 
     @wkenddate datetime = '2016-04-05' 

;WITH N(N)AS 
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)), 
tally(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a,N b,N c,N d,N e,N f) 
SELECT 
    CAST(DATEADD(d, 0, N) as DATE) WEEKEND 
FROM tally 
WHERE 
    N between datediff(d, 0, @wkstartdate) and datediff(d, 0, @wkenddate) 
    AND N % 7 in(5,6) 

Kết quả:

day 
2015-12-06 
2015-12-12 
2015-12-13 
... 
... 
2016-04-03 
Các vấn đề liên quan