Créez une date du jour mois et année avec T-SQL

J’essaie de convertir une date avec des composants individuels tels que 12, 1, 2007 dans une date / heure dans SQL Server 2005. J’ai essayé les éléments suivants:

CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME) 

mais cela se traduit par la mauvaise date. Quelle est la manière correcte de transformer les trois valeurs de date en un format de date / heure correct.

En supposant que y, m, d sont tous int , que diriez-vous de:

 CAST(CAST(y AS varchar) + '-' + CAST(m AS varchar) + '-' + CAST(d AS varchar) AS DATETIME) 

S’il vous plaît voir mon autre réponse pour SQL Server 2012 et supérieur

Essaye ça:

 Declare @DayOfMonth TinyInt Set @DayOfMonth = 13 Declare @Month TinyInt Set @Month = 6 Declare @Year Integer Set @Year = 2006 -- ------------------------------------ Select DateAdd(day, @DayOfMonth - 1, DateAdd(month, @Month - 1, DateAdd(Year, @Year-1900, 0))) 

Il fonctionne également, a l’avantage de ne pas effectuer de conversions de chaînes, c’est donc un traitement purement arithmétique (très rapide) et il ne dépend d’aucun format de date. La capitalisation de SQL Server pour les valeurs datetime et smalldatetime est deux. valeur de la partie dont la première partie est un nombre entier représentant le nombre de jours depuis le 1er janvier 1900, et la seconde partie est une fraction décimale représentant la partie fractionnaire d’un jour (pour l’heure). ) traduit toujours directement à minuit le matin du 1er janvier 1900 …

ou, grâce à la suggestion de @brinary,

 Select DateAdd(yy, @Year-1900, DateAdd(m, @Month - 1, @DayOfMonth - 1)) 

Édité en octobre 2014. Noté par @cade Roux, SQL 2012 dispose désormais d’une fonction intégrée:
DATEFROMPARTS(year, month, day)
cela fait la même chose.

Édité le 3 octobre 2016 (Merci à @bambams de l’avoir remarqué, et @brinary pour le corriger), La dernière solution, proposée par @brinary. ne semble pas fonctionner pour les années bissextiles, sauf si l’addition d’années est effectuée en premier

 select dateadd(month, @Month - 1, dateadd(year, @Year-1900, @DayOfMonth - 1)); 

SQL Server 2012 possède une nouvelle fonction DATEFROMPARTS merveilleuse et attendue depuis longtemps (qui déclenchera une erreur si la date n’est pas valide – ma principale objection à une solution basée sur DATEADD pour résoudre ce problème):

http://msdn.microsoft.com/en-us/library/hh213228.aspx

 DATEFROMPARTS(ycolumn, mcolumn, dcolumn) 

ou

 DATEFROMPARTS(@y, @m, @d) 

Ou en utilisant une seule fonction dateadd:

 DECLARE @day int, @month int, @year int SELECT @day = 4, @month = 3, @year = 2011 SELECT dateadd(mm, (@year - 1900) * 12 + @month - 1 , @day - 1) 

SQL Server 2012 a une fonction qui créera la date en fonction des pièces ( DATEFROMPARTS ). Pour le rest d’entre nous, voici une fonction de db que j’ai créée qui déterminera la date à partir des parties (merci @Charles) …

 IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[func_DateFromParts]')) DROP FUNCTION [dbo].[func_DateFromParts] GO CREATE FUNCTION [dbo].[func_DateFromParts] ( @Year INT, @Month INT, @DayOfMonth INT, @Hour INT = 0, -- based on 24 hour clock (add 12 for PM :) @Min INT = 0, @Sec INT = 0 ) RETURNS DATETIME AS BEGIN RETURN DATEADD(second, @Sec, DATEADD(minute, @Min, DATEADD(hour, @Hour, DATEADD(day, @DayOfMonth - 1, DATEADD(month, @Month - 1, DATEADD(Year, @Year-1900, 0)))))) END GO 

Vous pouvez l’appeler comme ça …

 SELECT dbo.func_DateFromParts(2013, 10, 4, 15, 50, DEFAULT) 

Résultats…

 2013-10-04 15:50:00.000 

Essayez CONVERT au lieu de CAST.

CONVERT permet un troisième paramètre indiquant le format de la date.

La liste des formats est ici: http://msdn.microsoft.com/en-us/library/ms187928.aspx

La mise à jour après qu’une autre réponse ait été sélectionnée comme réponse “correcte”:

Je ne comprends pas vraiment pourquoi une réponse est sélectionnée qui dépend clairement des parameters NLS sur votre serveur, sans indiquer cette ressortingction.

Vous pouvez aussi utiliser

 select DATEFROMPARTS(year, month, day) as ColDate, Col2, Col3 From MyTable Where DATEFROMPARTS(year, month, day) Between @DateIni and @DateEnd 

Fonctionne en SQL depuis la version 2012 et AzureSQL

Utiliser un sharepoint départ explicite «19000101» est plus sûr

 create function dbo.fnDateTime2FromParts(@Year int, @Month int, @Day int, @Hour int, @Minute int, @Second int, @Nanosecond int) returns datetime2 as begin -- Note! SQL Server 2012 includes datetime2fromparts() function declare @output datetime2 = '19000101' set @output = dateadd(year , @Year - 1900 , @output) set @output = dateadd(month , @Month - 1 , @output) set @output = dateadd(day , @Day - 1 , @output) set @output = dateadd(hour , @Hour , @output) set @output = dateadd(minute , @Minute , @output) set @output = dateadd(second , @Second , @output) set @output = dateadd(ns , @Nanosecond , @output) return @output end 

Si vous ne voulez pas en sortir, cela fonctionne aussi (mettez-le dans une fonction):

 DECLARE @Day int, @Month int, @Year int SELECT @Day = 1, @Month = 2, @Year = 2008 SELECT DateAdd(dd, @Day-1, DateAdd(mm, @Month -1, DateAdd(yy, @Year - 2000, '20000101'))) 

J’ajoute une solution sur une ligne si vous avez besoin d’une date / heure à partir des parties date et heure :

 select dateadd(month, (@Year -1900)*12 + @Month -1, @DayOfMonth -1) + dateadd(ss, @Hour*3600 + @Minute*60 + @Second, 0) + dateadd(ms, @Millisecond, 0) 

Essayer

 CAST(STR(DATEPART(year, DATE))+'-'+ STR(DATEPART(month, DATE)) +'-'+ STR(DATEPART(day, DATE)) AS DATETIME) 

Pour les versions de SQL Server inférieures à 12, je peux recommander l’utilisation de CAST en combinaison avec SET DATEFORMAT

 -- 26 February 2015 SET DATEFORMAT dmy SELECT CAST('26-2-2015' AS DATE) SET DATEFORMAT ymd SELECT CAST('2015-2-26' AS DATE) 

comment vous créez ces chaînes est à vous

Essayez cette requête:

  SELECT SUBSTRING(CONVERT(VARCHAR,JOINGDATE,103),7,4)AS YEAR,SUBSTRING(CONVERT(VARCHAR,JOINGDATE,100),1,2)AS MONTH,SUBSTRING(CONVERT(VARCHAR,JOINGDATE,100),4,3)AS DATE FROM EMPLOYEE1 

Résultat:

 2014 Ja 1 2015 Ja 1 2014 Ja 1 2015 Ja 1 2012 Ja 1 2010 Ja 1 2015 Ja 1 

Personnellement, je préfère Subssortingng car il fournit des options de nettoyage et la possibilité de diviser la chaîne si nécessaire. L’hypothèse est que les données sont au format «jj, mm, aaaa».

 --2012 and above SELECT CONCAT ( RIGHT(REPLACE(@date, ' ', ''), 4) ,'-' ,RIGHT(CONCAT('00',SUBSTRING(REPLACE(@date, ' ', ''), CHARINDEX(',', REPLACE(@date, ' ', '')) + 1, LEN(REPLACE(@date, ' ', '')) - CHARINDEX(',', REPLACE(@date, ' ', '')) - 5)),2) ,'-' ,RIGHT(CONCAT('00',SUBSTRING(REPLACE(@date, ' ', ''), 1, CHARINDEX(',', REPLACE(@date, ' ', '')) - 1)),2) ) --2008 and below SELECT RIGHT(REPLACE(@date, ' ', ''), 4) +'-' +RIGHT('00'+SUBSTRING(REPLACE(@date, ' ', ''), CHARINDEX(',', REPLACE(@date, ' ', '')) + 1, LEN(REPLACE(@date, ' ', '')) - CHARINDEX(',', REPLACE(@date, ' ', '')) - 5),2) +'-' +RIGHT('00'+SUBSTRING(REPLACE(@date, ' ', ''), 1, CHARINDEX(',', REPLACE(@date, ' ', '')) - 1),2) 

Voici une démonstration de la façon dont il peut être poursuivi si les données sont stockées dans une colonne. Inutile de dire que son idéal pour vérifier l’ensemble de résultats avant d’appliquer à la colonne

 DECLARE @Table TABLE (ID INT IDENTITY(1000,1), DateSsortingng VARCHAR(50), DateColumn DATE) INSERT INTO @Table SELECT'12, 1, 2007',NULL UNION SELECT'15,3, 2007',NULL UNION SELECT'18, 11 , 2007',NULL UNION SELECT'22 , 11, 2007',NULL UNION SELECT'30, 12, 2007 ',NULL UPDATE @Table SET DateColumn = CONCAT ( RIGHT(REPLACE(DateSsortingng, ' ', ''), 4) ,'-' ,RIGHT(CONCAT('00',SUBSTRING(REPLACE(DateSsortingng, ' ', ''), CHARINDEX(',', REPLACE(DateSsortingng, ' ', '')) + 1, LEN(REPLACE(DateSsortingng, ' ', '')) - CHARINDEX(',', REPLACE(DateSsortingng, ' ', '')) - 5)),2) ,'-' ,RIGHT(CONCAT('00',SUBSTRING(REPLACE(DateSsortingng, ' ', ''), 1, CHARINDEX(',', REPLACE(DateSsortingng, ' ', '')) - 1)),2) ) SELECT ID,DateSsortingng,DateColumn FROM @Table