2016-05-18 5 views
3

У меня есть datetime столбец ArrivalDateTime, который хранится как значение varchar.SQL Server 2008: преобразование Varchar в Datetime

Скажем, если значение 20161212093256, я хочу, чтобы выход был 2016-12-12 09:32:56.

Я мог бы получить дату в формате даты и времени, как показано ниже.

SELECT 
    CONVERT(DATETIME2(0), LEFT('20161212093256', 8)) 

Это возвращает результат как 2016-12-15 00:00:00.

Я попробовал следующий запрос, чтобы получить часть времени.

SELECT 
    CONVERT(DATE, LEFT('20161212093256', 8)) + ' ' + 
    CONVERT(TIME, RIGHT('20161212093256', 6)) 

Но это выдает ошибку:

The data types date and varchar are incompatible in the add operator

Как я могу получить как дата и время часть в формате datetime?

+2

прочитанное Аарон Бертрана (http://sqlblog.com/blogs/aaron_bertrand /archive/2009/10/12/bad-habits-to-kick-using-the-wrong-data-type.aspx). –

+0

Спасибо, помощник за указатель. К сожалению, я должен использовать столбец, созданный кем-то другим. Теперь я не могу изменить свой тип данных. – turbo88

+0

@ turbo88 вы не можете просто игнорировать эту ошибку проектирования, так как это влияет как на индексирование, запрос и производительность. Используя произвольную строку вместо даты, вы отключите все оптимизации запросов, связанных с датами.Перед запросом вам нужно будет преобразовать любые критерии даты в этот произвольный формат. Вы не сможете использовать какие-либо функции, связанные с датой, без разбора. И, наконец, механизм запроса должен будет обрабатывать и передавать каждую отдельную результирующую строку, когда он может использовать операции или индексы на основе набора, включающие столбец даты. Это приведет к огромному штрафу за производительность –

ответ

2

Сначала введите компонент даты и преобразуйте его в DATETIME, а затем получите компонент времени и преобразуйте его в DATETIME. Наконец, добавить два результата:

SELECT 
    CONVERT(DATETIME,LEFT('20161212093256', 8)) + 
    CONVERT(DATETIME, 
     LEFT(RIGHT('20161212093256', 6), 2) + ':' + 
     SUBSTRING(RIGHT('20161212093256', 6), 3, 2) + ':' + 
     RIGHT(RIGHT('20161212093256', 6), 2) 
    ) 

Для дальнейшего объяснения, результат первого преобразования является дата компонента:

2016-12-12 00:00:00.000 

Второе преобразование компонент времени, но когда вы преобразуйте его в DATETIME, добавив его к дате 0 или '1900-01-01', поэтому результат:

1900-01-01 09:32:56.000 

Затем добавьте оба DATETIME с, чтобы получить:

2016-12-12 09:32:56.000 

Чтобы избавиться от компонента мс:

SELECT 
    CONVERT(DATETIME,LEFT('20161212093256', 8)) + 
    CONVERT(DATETIME, 
     LEFT(RIGHT('20161212093256', 6), 2) + ':' + 
     SUBSTRING(RIGHT('20161212093256', 6), 3, 2) + ':00' 
    ) 
+0

Brilliant. Есть ли способ игнорировать миллисекунды? – turbo88

0

Try это,

DECLARE @V_STR VARCHAR(20) = '20161212093256' 
SELECT CONVERT(SMALLDATETIME,LEFT(@V_STR,8) +' '+  --date 
       SUBSTRING(@V_STR,9,2)+':'+    --hour 
       SUBSTRING(@V_STR,11,2)+':'+    --minute 
       SUBSTRING(@V_STR,13,2)) AS DATE_TIME --second 
+0

Отображает дату и время в двух отдельных столбцах. Я хочу, чтобы они были в одной колонке. – turbo88

0

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

select concat(CONVERT(DATE, LEFT('20161212093256', 8)) , ' ' , CONVERT(TIME, substring(RIGHT('20161212093256', 6),1,2)+ ':' + substring(RIGHT('20161212093256', 4),1,2) + ':' +RIGHT('20161212093256', 2))) 

выше будет показывать время с милисекунд, ниже без миллисекунды [Плохие привычки пинать: неправильный выбор типа данных]

select concat(CONVERT(DATE, LEFT('20161212093256', 8)) , ' ' , substring(RIGHT('20161212093256', 6),1,2)+ ':' + substring(RIGHT('20161212093256', 4),1,2) + ':' +RIGHT('20161212093256', 2)) 
0
SELECT STUFF(STUFF(STUFF(STUFF(STUFF('20161212093256', 5, 0, '-'), 8, 0, '-'), 11, 0, ' '), 14, 0, ':'), 17, 0, ':') 
Смежные вопросы