2017-01-05 5 views
0

Ich versuche, eine SQL While-Schleife zu schreiben, um ein Datum zu erhöhen, bis es ein Datum in zwei anderen Tabellen nicht paaren und ist kein Samstag oder Sonntag.SQL-Server während Datum nicht Wochenende oder ein bestimmtes Datum

So etwas wie dieses

DECLARE @DueDate datetime 
SELECT @DueDate = datetime FROM tbl_status WHERE (parent_id = @ComplaintId) 
WHILE((SELECT COUNT(date) FROM tbl1 WHERE(date = @DueDate)) > 0 AND (SELECT COUNT(date) FROM tbl2 WHERE(date = @DueDate)) > 0 AND DATEPART(d,@DueDate) = 'Saturday' AND DATEPART(d,@DueDate) = 'Sunday') 
BEGIN 
    @DueDate = DATEADD(d,1,@DueDate) 
END 

Kann mir jemand helfen

dank

+1

Und das Problem ist? – Sachin

+2

Sie sollten dafür keine Schleife verwenden. Sie sollten einen Satz basierend verwenden, der das Mindestdatum findet, das größer ist als Ihr Quelldatum, das nicht in den anderen zwei Tabellen oder einem Samstag/Sonntag ist. – iamdave

Antwort

1

Wie ich in meinem Kommentar erwähnt, Sie in einer sehr ineffizienten Weise mit while-Schleife darüber gehen.

Wenn Sie nicht über eine Tabelle der Daten müssen in einer Lookup zu verwenden, können Sie ein mit einer abgeleiteten Tabelle erstellen, auch als Common Table Expression bekannt:

-- Set up the test data: 
declare @t1 table (d date); 
declare @t2 table (d date); 
insert into @t1 values('20161230'),('20170111'),('20170110'); 
insert into @t2 values('20161225'),('20170105'),('20170106'); 

-- Declare your DueDate: 
declare @DueDate date = '20170105'; 


-- Use a CTE to build a table of dates. You will want to set the Start and End dates automatically with SELECT statements: 
declare @DatesStart date = '20161201'; 
declare @DatesEnd date = '20170225'; 

with Tally0 as 
(
    select x from (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) as x(x) 
) 
,Tally1 as 
(
    select row_number() over (order by (select null))-1 as rn 
    from Tally0 t1    -- 10 rows  -- Add more CROSS APPLY joins 
     cross apply Tally0 t2 -- 100 rows  -- to get enough rows to cover 
     cross apply Tally0 t3 -- 1000 rows -- your date range. 
) 
,Dates as 
(
    select dateadd(d,t.rn,@DatesStart) as DateValue 
    from Tally1 t 
    where t.rn <= datediff(d,@DatesStart,@DatesEnd) 
) 
select min(d.DateValue) as NextDate  -- SELECT the next available Date. 
from Dates d 
    left join @t1 t1 
     on(d.DateValue = t1.d) 
    left join @t2 t2 
     on(d.DateValue = t2.d) 
where t1.d is null      -- That isn't in either table 
    and t2.d is null     -- and isn't on a Saturday or Sunday. 
    and datename(weekday,d.DateValue) not in('Saturday','Sunday') 
    and d.DateValue > @DueDate 
+0

Da Sie über die Leistung sprechen, möchten Sie vielleicht eine rekursive CTE wie diese überdenken. Was Sie haben, ist im Grunde genommen das Gleiche wie eine Schleife, aber es sieht so aus, als wäre es auf Basis gesetzt, weil es keine Schleife gibt. Lesen Sie diesen Artikel zum Thema. http://www.sqlservercentral.com/articles/T-SQL/74118/ Anstelle der rekursiven Cte mit einer Tally-Tabelle würde helfen, diesen Teil Ihrer Abfrage. Ungeachtet +1 von mir, denn das ist eine gute Lösung. :) –

+1

@SeanLange Richtig bist du, bearbeitet zu Tally Table Ansatz. – iamdave

Verwandte Themen