Создайте дату с дневного месяца и года с помощью T-SQL
Я пытаюсь преобразовать дату с отдельными частями, такими как 12, 1, 2007, в дату и время в SQL Server 2005. Я пробовал следующее:
CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME)
но это приводит к неправильной дате. Каков правильный способ превратить три значения даты в правильный формат даты и времени.
- Можно ли установить начало недели для функции T-SQL DATEDIFF?
- Linq to Sql: множественные левые внешние соединения
- Оператор SQL MERGE для обновления данных
- Создание таблицы HTML с SQL FOR XML
- Кодировка Base64 в SQL Server 2005 T-SQL
- Использование псевдонимов в разделе «Где» или «Альтернативный вариант»?
- Как получить результат sp_executesql в переменную?
- Использование курсора с динамическим SQL в хранимой процедуре
- Как округлить время в T-SQL
- Преобразование Xml в таблицу SQL Server
- Результаты запроса T-SQL по результатам запроса
- Повороты с динамическими столбцами в SQL Server
- T-SQL выбирает запрос для удаления нечисловых символов
Предполагая, что 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