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
risposta
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
Puoi collegare '20110508' Torno 2011-04-23 00: 00: 00.000 – SQLMenace
-1 Questo non ha fornito una risposta corretta per i miei 7 casi di test ... – mellamokb
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
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
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
???, vedi codice aggiunto, usa getdate() – SQLMenace
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
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)
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
Errore mio, dovrebbe testare. Offset della data creata di -15 giorni, per evitare di utilizzare il CASO QUANDO POI. – MatBailie
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
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]
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.
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.
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
domanda, perché in SQL? – rsplak
Hai fatto un tentativo? Hai del codice che hai provato? – YetAnotherUser
Questa funzione passerà sempre la data corrente o potrà essere passata in qualsiasi momento? – mellamokb