2013-08-23 6 views
0

Я импортировать данные из другой системы и даты и времени хранится в виде строки в формате:Преобразование строки в дату времени в SQL

20061105084755ES 

yyyymmddhhmmss(es/ed) где es является EST и ed является EDT.

Мне нужно будет запросить эту таблицу за последние 30 дней. Я использую запрос на преобразование:

select convert(
    datetime, 
    left(cdts, 4)+'-'+substring(cdts, 5,2)+'-'substring(cdts, 7,2)+' '+substring(cdts, 9,2) +':'+substring(cdts, 11,2)+':'+substring(cdts, 13,2) 
as dt 
from tb1 
where dt < getdate()-30 

Я ищу более эффективный запрос, который сократит время. В этой таблице содержится около 90 миллионов записей, и запрос выполняется навсегда.

+2

Возможно, вы захотите удалить эту фотографию и на самом деле вставить текст запроса. Для некоторых из нас (я старею?) Эту картину действительно очень трудно читать. Кроме того, нам обычно нравится видеть весь запрос и, если имеется, план выполнения. Первый вопрос, который люди зададут себе, заключается в том, является ли это преобразование проблемой или чем-то еще - как объединение между таблицами без использования индексов. – NotMe

ответ

1

Один из возможных вариантов - добавить столбец даты в таблицу и заполнить эту информацию при загрузке. Таким образом, преобразование выполняется, прежде чем вам нужно будет запросить его.

Затем убедитесь, что у вас есть индекс в этом поле, которое может использовать фактический запрос.

+0

спасибо за ответ. У меня есть права только на запрос таблиц. –

0
convert(datetime,stuff(stuff(stuff(datevalue, 9, 0, ' '), 12, 0, ':'), 15, 0, ':')) 

или

Convert(time,Dateadd(SECOND, 
     Right(DateValue,2)/1, 
     Dateadd(MINUTE, 
       Right(DateValue,4)/100, 
       Dateadd(hour, 
         Right(DateValue,6)/10000, 
         '1900-01-01')))) + 
convert(datetime,LEFT(datevalue,8)) 

Link

2

Нет вычисления во время выполнения не собирается ускорить этот запрос, если вы выполняете вычисления, а затем нужно отфильтровать от результата вычисления - SQL Сервер будет вынужден выполнять сканирование таблицы. Основная проблема заключается в том, что вы выбрали сохранение своих дат в виде строки. По целому ряду причин это ужасное решение. Является ли индекс столбца индексированным как минимум? Если это так, то это может помочь получить данные только за последние 30 дней:

DECLARE @ThirtyDays CHAR(8); 
SET @ThirtyDays = CONVERT(CHAR(8),DATEADD(DAY,DATEDIFF(DAY,0,GETDATE()),0)-30,112); 

SELECT ... 
WHERE cdts >= @ThirtyDays; 

Если вам необходимо вернуть все данные из всей истории, за исключением последних 30 дней, это не собирается помогите, потому что, если вы не просто извлекаете данные из индексированного столбца, наиболее эффективным методом получения большей части данных в таблице является использование кластерного сканирования индекса. (Если вы получаете узкий набор столбцов, он может выбрать сканирование индекса, если у вас есть индекс покрытия.) Таким образом, ваше узкое место в большинстве этих сценариев не является чем-то, что может исправить формула, а скорее время, которое требуется фактически получать большой объем данных, передавать их по сети и визуализировать их на клиенте.

Кроме того, как в сторону, вы не можете сделать это:

SELECT a + b AS c FROM dbo.somewhere 
WHERE c > 10; 

c не существует в dbo.somewhere, это выражение получено в SELECT списке. Список SELECT анализируется вторым последним (прямо перед ORDER BY), поэтому вы не можете ссылаться на что-то в предложении WHERE, которого еще нет. Типичными обходными методами являются повторение выражения или использование подзапроса/CTE.

Смежные вопросы