Запрос к базе данных с использованием той же даты не возвращает данные - PullRequest
2 голосов
/ 02 марта 2010

У меня небольшая проблема с запросом. Я выбираю данные с помощью команды Между, но когда я выбираю начальную дату, равную конечной дате, запрос не показывает данные.

Я знаю, что проблема в формате. В своей базе данных я получил что-то вроде этого: 2009-05-22 15: 32: 52.000. Но когда я отправляю параметр даты со страницы ASP.NET, я отправлял только дату (2009-05-22).

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

Я думал добавить 1 день к конечной дате, поэтому, когда пользователь выбирает ту же дату, я изменяю диапазон за сценой и затем показываю данные. Как вы думаете?

Что бы вы сделали?

Ответы [ 8 ]

3 голосов
/ 02 марта 2010

Когда вы отправляете дату типа 2009-05-22, сервер sql интерпретирует ее как 2009-05-22 00:00:00.000. Это означает, что когда вы используете эту дату с запросом между, где «начальная дата равна конечной дате», вы проверяете диапазон ровно в одну миллисекунду.

Вместо этого вам нужно установить значение 2nd между значениями до конца дня, чтобы ваше выражение между ними охватывало полный однодневный диапазон. Или я предпочитаю использовать два выражения вроде этого:

WHERE ([datetimecolumn] >= '2009-05-22' AND [datetimecolumn] < '2009-05-23')

Обратите внимание на разницу в операторах сравнения; конец диапазона не включительно.

3 голосов
/ 02 марта 2010

2009-05-22 будет переводиться как 2009-05-22 00:00:00, поэтому установка начала и конца одинакова будет выбирать только записи, которые происходят ровно в полночь. Добавление одного дня (от полуночи до полуночи) обычно будет достаточно, если у вас нет точек данных, встречающихся слишком часто. Если данных много, лучше всего установить время окончания 23: 59: 59.999

.
1 голос
/ 02 марта 2010

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

Я бы порекомендовал не делать никаких интервалов от одной секунды до полуночи, поскольку степень детализации типа данных меньше одной секунды, и поэтому такие диапазоны неверны.

В качестве альтернативы, оригинальное предложение по сокращению времени и добавлению одного полного дня в диапазон должно работать нормально, если вы измените его с BETWEEN на "table.column <= @date AND @date <table.column + 1 "(что делает его исключительным интервалом в верхней части). </p>

1 голос
/ 02 марта 2010

Когда мне нужно получить все результаты за день, я создаю DateTime без компонента времени (0:00), а затем добавляю день и вычитаю секунду, чтобы получить DateTime с компонентом времени 23:59:59. Класс DateTime в .NET делает это довольно легко.

                DateTime dtStart = new DateTime( 2009, 5, 22 );
            DateTime dtEnd = dtStart.AddDays( 1 ).AddSeconds( -1 );
0 голосов
/ 02 марта 2010

пара приведенных ответов действительно помогла бы, я использовал этот метод, если он вас интересует,

    Select * from table1 Year(DtaeColumn)=Year(@OurDate) and Month(DtaeColumn)=Month
(@OurDate)  and Day(DtaeColumn)=Day(@OurDate)

это не оставляет места ни для чего эле ....

0 голосов
/ 02 марта 2010

Если у вас есть ввод скажем @matchDate ... вы можете создать дату начала / окончания для вашего диапазона. Вы должны использовать @startDate в качестве точки времени 0 для вашей даты, при этом @endDate это значение +1. Вам нужно сопоставить> = @startDate и <@ endDate. </p>

@matchDate DATETIME -- passed in with a given datetime
...
DECLARE @startDate DATETIME;
DECLARE @endDate DATETIME;

-- this will give you the DateTime without the Time part, note if you 
-- are storing dates in UTC, you will want to pass in your starting 
-- DateTime as the UTC zero hour, and skip this conversion.
SET @startDate = DATEADD(day, 0, DATEDIFF(day, 0, @created_date))

-- this will give you the @startDate + 1 Day
Set @endDate = DATEADD(dd, 1, @startDate);

...
SELECT ... 
FROM ... 
WHERE [MyDateCol] >= @startDate AND [MyDateCol] < @endDate

Когда вы делаете соответствующую дату для сопоставления, лучше всего указать диапазон, вы МОЖЕТЕ сделать сокращение как вашей даты совпадения, так и даты вашего столбца до части даты, но это будет меньше быстрее, чем использование> = и <для диапазона. </p>

Опять же, при хранении в UTC, вы захотите иметь начало в UTC. Что я рекомендую для приложений, которые будут обслуживать несколько часовых поясов. Недавно я опубликовал статью о выполнении постраничных результатов в sproc , которая включает совпадение даты и времени, если вам интересно.

0 голосов
/ 02 марта 2010

У вас есть 2 варианта ... либо тайно сделать диапазон дат, добавив один день введенную дату поиска, а затем выполнив диапазон дат или выполнив выбор, где вы сравниваете только часть даты в базе данных с данными искать с помощью DATEPART.

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

http://www.w3schools.com/Sql/func_datepart.asp

если вы собираетесь сделать диапазон данных, то сделайте это

ГДЕ дата> = 'введенная дата' И данные <'введенная дата + 1' </p>

вместо того, чтобы пытаться поймать самую последнюю секунду дня, чтобы вы могли сделать <= в конце части дня </p>

0 голосов
/ 02 марта 2010

попробуйте изменить параметр конечной даты перед передачей int в select. Так что, если конечная дата 2009-05-22, сделайте это 2009-05-22 23: 59: 59.00 Я знаю, что это не лучшее решение для жесткого кодирования таких вещей, но это легко сделать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...