J'essaie de convertir une date avec des pièces individuelles telles que 12, 1, 2007 en une date/heure dans SQL Server 2005. J'ai essayé les solutions suivantes:
CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME)
mais cela donne une mauvaise date. Quelle est la bonne façon de convertir les trois valeurs de date en un format de date/heure approprié?.
En supposant que y, m, d
sont tous int
, que diriez-vous:
CAST(CAST(y AS varchar) + '-' + CAST(m AS varchar) + '-' + CAST(d AS varchar) AS DATETIME)
Veuillez consulter mon autre réponse pour SQL Server 2012 et versions ultérieures
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)))
Cela fonctionne aussi, offre l’avantage supplémentaire de ne pas effectuer de conversions de chaînes. Il s’agit donc d’un traitement arithmétique pur (très rapide) et ne dépend pas du format de date. Il tire parti du fait que la représentation interne de SQL Server pour les valeurs datetime et smalldatetime est deux la valeur de la partie dont la première partie est un 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 décimale d'un jour (pour l'heure) --- Donc la valeur entière 0 (zéro) ) 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. Comme noté par @cade Roux, SQL 2012 a maintenant une fonction intégrée:DATEFROMPARTS(year, month, day)
Cela fait la même chose.
Édité le 3 oct. 2016, (Merci à @bambams pour l'avoir remarqué et à @brinary pour l'avoir corrigé), dernière solution proposée par @brinary. ne semble pas fonctionner pendant des années bissextiles à moins que les années ne soient ajoutées en premier
select dateadd(month, @Month - 1,
dateadd(year, @Year-1900, @DayOfMonth - 1));
SQL Server 2012 a une nouvelle fonction DATEFROMPARTS merveilleuse et attendue (qui générera une erreur si la date est invalide - ma principale objection à une solution à ce problème basée sur DATEADD):
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 reste d’entre nous, voici une fonction de base de données que j’ai créée et qui déterminera la date 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 autorise 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
Mettre à jour après qu'une autre réponse a été sélectionnée comme réponse "correcte":
Je ne comprends pas vraiment pourquoi une réponse sélectionnée dépend clairement des paramètres NLS sur votre serveur, sans indiquer cette restriction.
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 ver.2012 et Azure SQL
Il est plus sûr et plus judicieux d'utiliser un point de départ explicite, '19000101'
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
J'ajoute une solution sur une ligne si vous avez besoin d'une date/heure à partir de parties de date et d'heure:
select dateadd(month, (@Year -1900)*12 + @Month -1, @DayOfMonth -1) + dateadd(ss, @Hour*3600 + @Minute*60 + @Second, 0) + dateadd(ms, @Millisecond, 0)
Si vous ne voulez pas garder les chaînes hors de celui-ci, 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')))
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 dépend de 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
Je sais que l'OP demande une réponse à SQL 2005, mais la question est assez ancienne. Par conséquent, si vous utilisez SQL 2012 ou une version ultérieure, vous pouvez utiliser les éléments suivants:
SELECT DATEADD(DAY, 1, EOMONTH(@somedate, -1))
Personnellement, je préfère Substring car il fournit des options de nettoyage et la possibilité de scinder 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 le résultat avant d'appliquer à la colonne
DECLARE @Table TABLE (ID INT IDENTITY(1000,1), DateString 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(DateString, ' ', ''), 4)
,'-'
,RIGHT(CONCAT('00',SUBSTRING(REPLACE(DateString, ' ', ''), CHARINDEX(',', REPLACE(DateString, ' ', '')) + 1, LEN(REPLACE(DateString, ' ', '')) - CHARINDEX(',', REPLACE(DateString, ' ', '')) - 5)),2)
,'-'
,RIGHT(CONCAT('00',SUBSTRING(REPLACE(DateString, ' ', ''), 1, CHARINDEX(',', REPLACE(DateString, ' ', '')) - 1)),2)
)
SELECT ID,DateString,DateColumn
FROM @Table