Создайте дату с дневного месяца и года с помощью T-SQL

Я пытаюсь преобразовать дату с отдельными частями, такими как 12, 1, 2007, в дату и время в SQL Server 2005. Я пробовал следующее:

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

но это приводит к неправильной дате. Каков правильный способ превратить три значения даты в правильный формат даты и времени.

Предполагая, что y, m, d все int , как насчет:

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

См. Мой другой ответ для SQL Server 2012 и выше

Попробуй это:

 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))) 

Он также работает, добавляет преимущества не делать каких-либо преобразований строк, поэтому это чистая арифметическая обработка (очень быстро) и не зависит от формата даты. Это основывается на том, что внутреннее представление SQL Server для значений datetime и smalldatetime – это два значение части, первая часть которого представляет собой целое число, представляющее число дней с 1 января 1900 года, а вторая часть представляет собой десятичную дробь, представляющую дробную часть за один день (на время) — Итак, целочисленное значение 0 (ноль ) всегда переводится непосредственно в полуночное утро 1 января 1900 года …

или, благодаря предложению из @brinary,

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

Отредактированный октябрь 2014 года. Как отмечалось в @cade Roux, SQL 2012 теперь имеет встроенную функцию:
DATEFROMPARTS(year, month, day)
что делает то же самое.

Отредактировано 3 октября 2016 года (спасибо @bambams за это замечание и @brinary за его исправление). Последнее решение, предложенное @brinary. похоже, не работает в високосные годы, если сначала не выполняется добавление лет

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

SQL Server 2012 имеет замечательную и долгожданную новую функцию DATEFROMPARTS (что приведет к ошибке, если дата недействительна – мое основное возражение против решения DATEADD для этой проблемы):

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

 DATEFROMPARTS(ycolumn, mcolumn, dcolumn) 

или

 DATEFROMPARTS(@y, @m, @d) 

Или используя только одну функцию 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 имеет функцию, которая будет создавать дату на основе частей ( DATEFROMPARTS ). Для остальных из нас, здесь создана функция db, которая будет определять дату из частей (спасибо @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 

Вы можете назвать это так …

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

Возвращает …

 2013-10-04 15:50:00.000 

Попробуйте CONVERT вместо CAST.

CONVERT разрешает третий параметр, указывающий формат даты.

Список форматов находится здесь: http://msdn.microsoft.com/en-us/library/ms187928.aspx

Обновление после того, как другой ответ был выбран как «правильный» ответ:

Я не понимаю, почему выбран ответ, который явно зависит от настроек NLS на вашем сервере, без указания этого ограничения.

Вы также можете использовать

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

Работает в SQL с версии ver.2012 и AzureSQL

Более безопасно и аккуратно использовать явную отправную точку «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 

Если вы не хотите, чтобы строки были из него, это также работает (поместите его в функцию):

 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'))) 

Я добавляю однострочное решение, если вам требуется дата и время с обеих частей даты и времени :

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

Пытаться

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

Для версий SQL Server ниже 12 я могу рекомендовать использование CAST в сочетании с 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) 

как вы создаете эти строки, зависит от вас

Попробуйте этот запрос:

  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 

Результат:

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

Я лично предпочитаю подстроку, поскольку она предоставляет параметры очистки и возможность разбивать строку по мере необходимости. Предполагается, что данные имеют формат «dd, mm, yyyy».

 --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) 

Вот демонстрация того, как его можно подавать в суд, если данные хранятся в столбце. Само собой разумеется, его идеальный вариант для проверки результата перед применением к столбцу

 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 
  • T-SQL Pivot? Возможность создания столбцов таблицы из значений строк
  • SET против SELECT - В чем разница?
  • Заменить новую строку в TSQL
  • Игнорирование параметра NULL в T-SQL
  • Как проверить, существует ли столбец в таблице SQL Server?
  • Isoweek в SQL Server 2005
  • Точность десятичного деления T-SQL
  • T-SQL: выбор строк для удаления с помощью соединений
  • Тестирование неравенства в T-SQL
  • Как преобразовать строку dd / mm / yyyy в datetime в SQL Server?
  • Как сделать SQL как% в Linq?
  • Давайте будем гением компьютера.