2011-05-13 16 views
5

Ho bisogno di scrivere una funzione o SP che restituisca la prima occorrenza del 15. Ad esempio, se ho passato la data come 8 maggio, dovrebbe tornare il 15 maggio. Se passerò il 30 maggio, allora dovrebbe tornare il 15 giugno.SQL Ottieni la prima occorrenza del 15 per una data

+0

domanda, perché in SQL? – rsplak

+1

Hai fatto un tentativo? Hai del codice che hai provato? – YetAnotherUser

+0

Questa funzione passerà sempre la data corrente o potrà essere passata in qualsiasi momento? – mellamokb

risposta

-1

provare

DATEADD(Day, DATEDIFF(Day, 15, Created), 0) AS CreatedDay 

spiegato qui http://improve.dk/archive/2006/12/13/sql-server-datetime-rounding-made-easy.aspx

usando quel link potete achive ciò che si vuole

UPDATE: capito male ... vedere Dems rispondere

+0

Puoi collegare '20110508' Torno 2011-04-23 00: 00: 00.000 – SQLMenace

+0

-1 Questo non ha fornito una risposta corretta per i miei 7 casi di test ... – mellamokb

+1

Il DateDiff ha bisogno di differire i mesi non i giorni Il codice sta arrotondando il Created fino al giorno più vicino e sottraendo 15 giorni ... – MatBailie

4

Un modo

DECLARE @d DATETIME 
    SELECT @d = '20110508' 
    --SELECT @d = '20110530' 


    SELECT CASE WHEN DAY(@d) > 15 
    THEN dateadd(mm, datediff(mm, 0, @d)+1, 0) + 14 
    ELSE dateadd(mm, datediff(mm, 0, @d)+0, 0)+ 14 end 
+0

Se cambi 'getdate()' a '@ d' penso che ce l'avresti. Funziona ora solo se stai usando un giorno che diventa 5-15 (o qualunque sia il risultato corretto per oggi.) – mellamokb

+0

???, vedi codice aggiunto, usa getdate() – SQLMenace

+0

Nel tuo primo esempio: 'SELEZIONA CASO QUANDO GIORNO (@d)> 15 THEN dateadd (mm, datediff (mm, 0, getdate()) + 1, 0) + 14 dateadd ELSE (mm, datediff (mm, 0, getdate()) + 0, 0) + 14 fine' questo è sbagliato. Provalo con '20110710' e otterrai 5-15. Ovviamente è sbagliato. Perché quelli 'getdate()' nel tuo primo esempio devono essere '@ d'. Non vi è alcuna indicazione da parte di OP che si è assunto che passeranno sempre la data corrente. – mellamokb

0

risposta di Rob è vicino ...

se si prende il datediff in mesi, invece di giorni, e rendere la vostra base l'15'th di un mese, poi aggiungere un mese in più ...

DATEADD(MONTH, DATEDIFF(MONTH, 14, Created) + 1, 14)

EDIT

modificati per utilizzare DATEDIFF MESE come funziona, non come ho pensato che dovrebbe funzionare;)

DATEADD(MONTH, DATEDIFF(MONTH, 0, Created - 15) + 1, 14)

+0

Non proprio: 5-1 -> 6-15, non è la prossima apparizione. 5-1 dovrebbe restituire ** 5-15 **. È necessario un controllo extra come '@ SQLMenace' da gestire prima del 15 ° rispetto al 15 °. – mellamokb

+0

Errore mio, dovrebbe testare. Offset della data creata di -15 giorni, per evitare di utilizzare il CASO QUANDO POI. – MatBailie

3

Come circa;

create function udf_getNextDate(@base datetime, @day int) returns datetime as begin 
    set @base = case when day(@base) > @day   
      then dateadd(month, 1, @base) 
     else @base 
    end 
    return dateadd(day, -day(@base) + @day, @base) 
end 

select 
    dbo.udf_getNextDate('08 may 2011', 15), 
    dbo.udf_getNextDate('30 may 2011', 15), 
    dbo.udf_getNextDate('16 dec 2011', 15), 
    dbo.udf_getNextDate('01 may 2011', 15) 

2011-05-15 00:00:00.000 
2011-06-15 00:00:00.000 
2012-01-15 00:00:00.000 
2011-05-15 00:00:00.000 
1

Solo un altro modo di farlo:

Declare @d datetime 

Set @d = getdate() 


Select Case 
      When DateDiff(Day, Day(@d), 15) < 0 then 
        DateAdd(month, 1, DateAdd(Day, DateDiff(Day, Day(@d), 15), @d)) 
      Else DateAdd(Day, DateDiff(Day, Day(@d), 15), @d) 
     End as [Next15th] 
0

Ecco una dichiarazione select per ottenere il primo 15 si verificano del mese di una certa data (qui: @mydate)

declare @mydate datetime 
      , @first15th datetime 
    set @mydate = convert(datetime,'2011/05/29 11:14:20.334') 
    set @first15th = 
     (select 
      dateadd(
      day, 
      15 - day(dateadd (day, 
           day(@mydate) - (day(@mydate)-15) , 
           @mydate) 
      ), 
      dateadd (day, 
        day(@mydate) - (day(@mydate)-15) , 
        @mydate) 
     ) 
    select @first15th //for 2011/05/29 11:14:20.334 => 2011/06/15 11:14:20.334 
         //for 2011/05/09 11:14:20.334 => 2011/05/15 11:14:20.334 

Ora dovresti essere in grado di cucinare qualche SP o Function da esso.

0

Io di solito fare qualcosa di simile:

declare 
    @date  datetime , 
    @target_day int 

set @date  = 'June 16, 2009' 
set @target_day = 15 

select date  = @date , 
     next_date = case when day(@date) <= @target_day 
        then dateadd(day,15-day(@date),@date) 
        else dateadd(day,15,dateadd(month,1,dateadd(day,-day(@date),@date))) 
        end 

che fare con l'ultimo giorno del mese è un pochino più complicato, dal mese sono un numero variabile di giorni, e la data di matematica di SQL Server è a volte un pochino barocco.

1

questa funzione potrebbe ti aiuta

create function Get15th(@date datetime) 
returns datetime 
as 
begin 
declare @resultdate datetime 
declare @y int 
declare @m int 
declare @d int 
set @y = datepart(year,@date) 
set @m = datepart(month,@date) 
set @d = datepart(day,@date) 
if(@d<=15) 
set @resultdate =cast((str(@y)+'-'+str(@m)+'-15') as datetime) 
else 
set @resultdate =cast((str(@y)+'-'+str(@m+1)+'-15') as datetime) 
return @resultdate 
end 
Problemi correlati