Ich versuche, ein Datum mit einzelnen Teilen wie 12, 1, 2007 in eine Datumszeit in SQL Server 2005 zu konvertieren. Ich habe Folgendes versucht:
CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME)
dies führt jedoch zu einem falschen Datum. Was ist der richtige Weg, um aus den drei Datumswerten ein geeignetes Datums- und Uhrzeitformat zu machen?.
Angenommen, y, m, d
sind alle int
, wie wäre es mit:
CAST(CAST(y AS varchar) + '-' + CAST(m AS varchar) + '-' + CAST(d AS varchar) AS DATETIME)
Siehe meine andere Antwort für SQL Server 2012 und höher
Versuche dies:
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)))
Es funktioniert auch und hat den zusätzlichen Vorteil, dass keine Zeichenfolgenkonvertierungen durchgeführt werden. Daher ist es eine reine arithmetische Verarbeitung (sehr schnell) und es ist nicht von einem Datumsformat abhängig. Dies basiert auf der Tatsache, dass die interne Darstellung von SQL Server für datetime- und smalldatetime-Werte zwei ist Teilwert, dessen erster Teil eine Ganzzahl ist, die die Anzahl der Tage seit dem 1. Januar 1900 darstellt, und dessen zweiter Teil ein Dezimalbruch ist, der den Bruchteil eines Tages (für die Zeit) darstellt --- Also der Ganzzahlwert 0 (Null) ) übersetzt immer direkt in Mitternachtsmorgen vom 1. Januar 1900 ...
oder, dank des Vorschlags von @brinary,
Select DateAdd(yy, @Year-1900,
DateAdd(m, @Month - 1, @DayOfMonth - 1))
Bearbeitet im Oktober 2014. Wie von @cade Roux bemerkt, verfügt SQL 2012 nun über eine integrierte Funktion:DATEFROMPARTS(year, month, day)
das macht das selbe.
Bearbeitet am 3. Oktober 2016 (Dank an @bambams für das Bemerken und @brinary für das Reparieren), Die letzte von @brinary vorgeschlagene Lösung. scheint nicht für Schaltjahre zu funktionieren, es sei denn, die Addition von Jahren wird zuerst durchgeführt
select dateadd(month, @Month - 1,
dateadd(year, @Year-1900, @DayOfMonth - 1));
SQL Server 2012 verfügt über eine wundervolle und lang erwartete neue DATEFROMPARTS-Funktion (die einen Fehler hervorruft, wenn das Datum ungültig ist - mein hauptsächlicher Einwand gegen eine DATEADD-basierte Lösung für dieses Problem):
http://msdn.Microsoft.com/de-de/library/hh213228.aspx
DATEFROMPARTS(ycolumn, mcolumn, dcolumn)
oder
DATEFROMPARTS(@y, @m, @d)
Oder verwenden Sie nur eine einzige Dateadd-Funktion:
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 verfügt über eine Funktion, die das Datum basierend auf den Teilen erstellt ( DATEFROMPARTS ). Für den Rest von uns ist hier eine Db-Funktion, die ich erstellt habe, die das Datum aus den Teilen bestimmt (danke @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
Man kann es so nennen ...
SELECT dbo.func_DateFromParts(2013, 10, 4, 15, 50, DEFAULT)
Kehrt zurück...
2013-10-04 15:50:00.000
Versuchen Sie CONVERT anstelle von CAST.
CONVERT erlaubt einen dritten Parameter, der das Datumsformat angibt.
Eine Liste der Formate finden Sie hier: http://msdn.Microsoft.com/de-de/library/ms187928.aspx
Aktualisieren, nachdem eine andere Antwort als "richtige" Antwort ausgewählt wurde:
Ich verstehe nicht wirklich, warum eine Antwort ausgewählt wird, die eindeutig von den NLS-Einstellungen auf Ihrem Server abhängt, ohne diese Einschränkung anzuzeigen.
Sie können auch verwenden
select DATEFROMPARTS(year, month, day) as ColDate, Col2, Col3
From MyTable Where DATEFROMPARTS(year, month, day) Between @DateIni and @DateEnd
Funktioniert in SQL seit ver.2012 und Azure SQL
Es ist sicherer und übersichtlicher, einen expliziten Startpunkt '19000101' zu verwenden.
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
Ich füge eine einzeilige Lösung hinzu, wenn Sie eine datetime aus Datums- und Zeitangaben benötigen:
select dateadd(month, (@Year -1900)*12 + @Month -1, @DayOfMonth -1) + dateadd(ss, @Hour*3600 + @Minute*60 + @Second, 0) + dateadd(ms, @Millisecond, 0)
Wenn Sie Strings nicht heraushalten wollen, funktioniert das auch (Füge es in eine Funktion ein):
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')))
Versuchen
CAST(STR(DATEPART(year, DATE))+'-'+ STR(DATEPART(month, DATE)) +'-'+ STR(DATEPART(day, DATE)) AS DATETIME)
Für SQL Server-Versionen unter 12 kann ich die Verwendung von CAST
in Kombination mit SET DATEFORMAT
empfehlen.
-- 26 February 2015
SET DATEFORMAT dmy
SELECT CAST('26-2-2015' AS DATE)
SET DATEFORMAT ymd
SELECT CAST('2015-2-26' AS DATE)
wie Sie diese Zeichenfolgen erstellen, liegt bei Ihnen
Versuchen Sie diese Abfrage:
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
Ergebnis:
2014 Ja 1
2015 Ja 1
2014 Ja 1
2015 Ja 1
2012 Ja 1
2010 Ja 1
2015 Ja 1
Ich weiß, dass das OP nach einer Antwort auf SQL 2005 fragt, aber die Frage ist ziemlich alt. Wenn Sie SQL 2012 oder höher ausführen, können Sie Folgendes verwenden:
SELECT DATEADD(DAY, 1, EOMONTH(@somedate, -1))
Ich persönlich bevorzuge Substrings, da es Bereinigungsoptionen bietet und die Möglichkeit besteht, die Zeichenfolge nach Bedarf zu teilen. Die Annahme ist, dass die Daten das Format 'TT, MM, JJJJ' haben.
--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)
Hier ist eine Demonstration, wie es verklagt werden kann, wenn die Daten in einer Spalte gespeichert sind. Es ist unnötig zu erwähnen, dass es ideal ist, die Ergebnismenge zu überprüfen, bevor Sie sie auf die Spalte anwenden
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