2012-06-26 4 views
1

Это сводит меня с ума, и не уверен, что я здесь отсутствует ..SQL заявление между датой

так вот мой столбец данных выглядит следующим образом:

StartDateTime: 
--------------- 
2012-01-17 11:13:46.530 
2012-01-17 11:17:22.530 
2012-02-17 11:31:22.223 

вот мой запрос пытается получить :

select * from tablName 
where convert(varchar(10), startDateTime, 101) between '2012-01-17' and '2012-01-17' 

Основываясь на вышесказанном, я должен получать ДВА строк? но это не так, он возвращает нулевые строки. что будет правильным способом?

PS: Я смотрел на MSDN сайт тоже:

+0

или я могу передать даты что-то вроде этого: '01/17/2012' –

+0

Что такое тип данных' StartDateTime'? –

+0

datatype is 'datetime' –

ответ

3

Ваш запрос будет только соответствовать даты, которые находятся между 2012-01-17 00:00:00 и 2012-01-17 00:00:00. Таким образом, единственные совпадения были бы тогда, когда дата точно равна 2012-01-17 00:00:00.

Вместо этого, я хотел бы сделать это:

declare @dateInput as DateTime 
set @dateInput = '2012-01-17' 

select * 
from tablName 
where startDateTime >= @dateInput 
    and startDateTime < dateadd(day, 1, @dateInput) 

Примечание: SQL Server 2008+ имеет новый тип Date данных без временной компоненты, которые могут сделать эти типы запросов более читаемым.

+0

'yyyy-mm-dd' зависит от языка для кастования в' datetime'. 'yyyymmdd' недвусмыслен. –

+0

, если я пробовал обе даты, чтобы они были такими же, как 'startDateTime> = '2012-01-17' и startDateTime <'2012-01-17' - возвращает нулевые строки –

+0

@Abu' '2012-01-17'' соответствует ' '2012-01-17 00: 00: 00''. Дополнительную информацию см. В моем обновленном ответе. – RedFilter

0

Вы используете поле datetime (я предполагаю). Не забывайте время:

select * from tablName 
where startDateTime between '2012-01-17' and '2012-01-17 23:59:59.997' 
+0

И если они используют 'datetime2'? Или позже измените колонку на это? –

+0

@Tahbaza: пользователь будет передавать параметры в качестве даты (01/17/2012) not datetime (2012-01-17 23: 59: 59.997) –

1

Существует в настоящее время больше информации, так что я буду добавлять более подходящий ответ. Требования теперь хранимая процедура передается параметр типа Дата, не DateTime, а желание вернуть строки из таблицы на основе критерия против поля DateTime имени StartDateTime ...

create procedure dbo.spGetEntriesForOneDay 
@DesiredDate DateTime 
as 
SET NOCOUNT ON; 
SET @DesiredDate = DATEADD(day, DATEDIFF(day, 0, @DesiredDate), 0) 

SELECT Field1, Field2 -- see note 1 
FROM dbo.TableName 
WHERE StartDateTime >= @DesiredDate -- see note 2 
    AND StartDateTime < DATEADD(day, 1, @DesiredDate) -- see note 3 

Примечание 1 : Не используйте * в производственном коде, особенно в хранимой процедуре. Помимо расточительства по возврату столбцов, вам, вероятно, не нужно и исключению оптимизации индекса покрытия для подмножества требуемых столбцов вам потребуется перекомпилировать эту хранимую процедуру всякий раз, когда базовая таблица будет изменена, чтобы избежать непредсказуемых результатов.

ПРИМЕЧАНИЕ 2: Избегайте обертывания полей в функции. Поле, не завернутое в функцию, потенциально может быть сопоставлено оптимизатором с индексом, в то время как поле, завернутое в функцию, никогда не будет.

ПРИМЕЧАНИЕ 3: @Martin Smith и @RedFilter верны в том, что точность .997 предполагает, что тип данных DateTime навсегда; этот подход является более перспективным доказательством, поскольку не делает предположений о точности данных.

+0

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

+0

ok - Я думал, что ваш параметр был типом даты, я буду изменять пример, чтобы быть DateTime – Tahbaza

+0

спасибо за ответ, но я ' m не уверен, что другой ответ от RedFilter? –

0

Вы можете использовать функцию DateDiff в предложении where. Это будет выглядеть следующим образом:

select col1, col2 from tablName where DateDiff(day, startDateTime, @DesiredDate) = 0 
Смежные вопросы