Получение строк между диапазонами дат не работает в SQL Server - PullRequest
0 голосов
/ 13 декабря 2011

В SQL Server 2008R2 загрузка данных между двумя датами не работает.

Я использую следующий код для получения строк из таблицы INVOICE, где CREATED_DATE находится между @startdate и @enddate, которые являются параметрами, которые я отправляю хранимой процедуре.

Select * 
from INVOICES INV 
where CONVERT(Varchar(10), INV.CREATED_DATE, 105)
      BETWEEN CONVERT(VARCHAR(10), @startdate, 105) 
          AND CONVERT(VARCHAR(10), @enddate, 105)

Он не работает должным образом, сводит меня с ума ..

Что я делаю не так? ..

Ответы [ 3 ]

8 голосов
/ 13 декабря 2011
select * from 
invoices inv 
where inv.created_date >= dateadd(dd, 0, datediff(dd, 0, @startdate))
    and inv.created_date < dateadd(dd, 1, datediff(dd, 0, @enddate))

Прежде всего, не конвертируйте даты начала / окончания и даты столбца в varchar, и если вы это сделаете, помните, что 105 (возвращает дд-мм-гггг) несопоставимо, 112 (возвращает ггггммдд) будет лучше (если вас интересует только часть даты).Но то, что я сказал, лучше не конвертировать и просто сравнивать даты.

Добавлено :

И небольшое объяснение: dateadd(dd, 0, datediff(dd, 0, @startdate)) - возвращает только часть даты datetime, dateadd(dd, 1, datediff(dd, 0, @startdate)) - возвращает только часть даты следующего дня.

Запрос возвращает все строки для ваших параметров включительно (независимо от часа).

2 голосов
/ 13 декабря 2011

Поскольку вы используете SQL Server 2008 R2, вы можете просто преобразовать все в формат DATE:

SELECT * 
FROM dbo.INVOICES INV 
WHERE CAST(INV.CREATED_DATE AS DATE) 
      BETWEEN CAST(@startdate AS DATE) AND CAST(@enddate AS DATE)

Поскольку вы используете тип DATE, вы не зависите ни от даты, ни от языка, ни от этих хитрых функций. SQL Server будет просто сравнивать даты - как и должно быть.

И, конечно: если вы сделаете параметры хранимой процедуры @startdate и @enddate для типа DATE с самого начала, то вы также можете сохранить эти две операции CAST тоже!

SELECT * 
FROM dbo.INVOICES INV 
WHERE CAST(INV.CREATED_DATE AS DATE) BETWEEN @startdate AND @enddate 

(и если вы сделали CREATED_DATE типа DATE - вы могли бы даже забыть о последнем CAST в выражении!)

1 голос
/ 13 декабря 2011

Default setting is yyyy-MM-dd

Если вы используете 105, что означает, что вы пытаетесь проанализировать дату как формат dmy, поэтому перед выполнением добавьте строку ниже в верхней части вашего запроса.

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