2009-06-23 7 views
5

Dans mon tableau j'ai un champ Month (tinyint) et un Day (tinyint). Je voudrais avoir une fonction qui prend ce mois et ce jour et produit un datetime pour la prochaine date (y compris l'année) donné ce mois et ce jour. Donc si j'avais Mois = 9, Jour = 7 cela produirait 9/7/2009.
Si j'avais Mois 1, Jour 1, il produirait 1/1/2010.SQL: Comment produire la date suivante donnée mois et jour

+0

comment savez-vous quelle année à utiliser? Supposons-nous simplement qu'il sera toujours basé sur la date actuelle? Aussi, quelle base de données utilisez-vous? – northpole

+0

C'est basé sur aujourd'hui. Alors disons aujourd'hui est le 23/06/2009. La date dans la table est month = 6, day = 22. Ensuite, je veux que ça retourne 22/06/2010 parce que c'est la date suivante. –

Répondre

2

quelque chose comme ça fonctionnerait. C'est une variante de votre méthode, mais elle n'utilise pas le format littéral MM/DD/YYYY, et elle ne va pas exploser contre les mauvaises entrées (pour le meilleur ou pour le pire).

declare @month tinyint 
declare @day tinyint 
set @month = 9 
set @day = 1 

declare @date datetime 

-- this could be inlined if desired 
set @date = convert(char(4),year(getdate()))+'0101' 
set @date = dateadd(month,@month-1,@date) 
set @date = dateadd(day,@day-1,@date) 

if @date <= getdate()-1 
    set @date = dateadd(year,1,@date) 

select @date 

Sinon, pour créer une chaîne au format AAAAMMJJ:

set @date = 
    right('0000'+convert(char(4),year(getdate())),4) 
+ right('00'+convert(char(2),@month),2) 
+ right('00'+convert(char(2),@day),2) 

Une autre méthode, qui évite littéraux tous ensemble:

declare @month tinyint 
declare @day tinyint 
set @month = 6 
set @day = 24 

declare @date datetime 
declare @today datetime 

-- get todays date, stripping out the hours and minutes 
-- and save the value for later 
set @date = floor(convert(float,getdate())) 
set @today = @date 

-- add the appropriate number of months and days 
set @date = dateadd(month,@month-month(@date),@date) 
set @date = dateadd(day,@day-day(@date),@date) 

-- increment year by 1 if necessary 
if @date < @today set @date = dateadd(year,1,@date) 

select @date 
1

Voici mon exemple sql jusqu'à présent. Je ne l'aime pas vraiment bien ...

DECLARE @month tinyint, 
    @day tinyint, 
    @date datetime 

SET @month = 1 
SET @day = 1 

-- SET DATE TO DATE WITH CURRENT YEAR 
SET @date = CONVERT(datetime, CONVERT(varchar,@month) + '/' + CONVERT(varchar,@day) + '/' + CONVERT(varchar,YEAR(GETDATE()))) 


-- IF DATE IS BEFORE TODAY, ADD ANOTHER YEAR 
IF (DATEDIFF(DAY, GETDATE(), @date) < 0) 
BEGIN 
    SET @date = DATEADD(YEAR, 1, @date) 
END 

SELECT @date 
+2

N'utilisez pas le format MM/JJ/AAAA pour les littéraux de date. Utilisez YYYYMMDD à la place. Cela évitera les problèmes de localisation et il trie correctement. –

+0

Sinon, je ne vois pas de problème avec votre méthode. Aimez-vous la conversion d'un littéral? –

+0

Il semble que quelque chose devrait être une solution facile. –

1

est ici une solution avec PostgreSQL

your_date_calculated = Year * 10000 + Month * 100 + Day 

vous donne une date comme 20090623.

select cast(cast(your_date_calculated as varchar) as date) + 1 
1

Voilà ma version. Le cœur de c'est à seulement deux lignes, en utilisant la fonction DATEADD, et il ne nécessite pas de conversion/de cordes, flotte ou toute autre chose:

DECLARE @Month TINYINT 
DECLARE @Day TINYINT 

SET @Month = 9 
SET @Day = 7 

DECLARE @Result DATETIME 

SET @Result = 
    DATEADD(month, ((YEAR(GETDATE()) - 1900) * 12) + @Month - 1, @Day - 1) 
IF (@Result < GETDATE()) 
    SET @Result = DATEADD(year, 1, @Result) 

SELECT @Result 
+0

Nice. Que diriez-vous d'une version en ligne pour éviter la surcharge de l'appel de fonction? Par exemple, SELECT DATEADD (année, , DATEADD (mois, (YEAR (GETDATE()) - 1900) * 12) + MonthField - 1, DayField - 1)) comme NewDate FROM .... –

Questions connexes