2017-02-17 3 views
-2

Перед нами стоит проблема, когда мы пытаемся выбрать записи из таблицы между двумя датами.Выбрать Между двумя датами в sql

Таблица структуры/типы данных:

 
    Slno (int, notnull, IsIdentity(yes)) 
    Name (string(50)) 
    StartDate (datetime) 
    EndDate (datetime) 

Образец данных:

 
Slno Name  StartDate     EndDate 
1  ABC  2017-02-17 00:00:00.000  2017-02-25 00:00:00.000 
2  ABD  2017-02-15 00:00:00.000  2017-02-25 00:00:00.000 
3  ABD  2017-02-17 00:00:00.000  2017-02-17 00:00:00.000 
4  ABD  2017-02-14 00:00:00.000  2017-02-18 00:00:00.000 
5  ABD  2017-02-17 00:00:00.000  2017-02-20 00:00:00.000 

Мы попытались запустить ниже SQL-запрос:

select * from dbo.XYZ where (getdate() between StartDate and EndDate) 

Выход составляет:

 
Slno Name  StartDate     EndDate 
1  ABC  2017-02-17     2017-02-25 
2  ABD  2017-02-17     2017-02-20 

Мы не получаем другие три ряда. Что я делаю не так?

+0

Какие типы данных являются startDate и EndDate? –

+0

'Slno' = 2 имеет' StartDate' = 2017-02-15 и 'Enddate' = 2017-02-25. Это опечатка в вашем выпуске? Кроме того, добавьте вывод 'getdate()', люди могут рассмотреть этот вопрос в будущем. – HoneyBadger

+0

Типы данных startDate и EndDate - это дата и время. – user3128590

ответ

-1

Getdate() означает текущее время и время. Таким образом, приведенный выше запрос возвращает 2 строки.

Вы можете передать этот запрос:

declare @minDate datetime 
declare @maxDate datetime 

select @minDate = MIN(StartDate) from dbo.XYZ 
select @maxDate = MAX(EndDate) from dbo.XYZ 

    select * from dbo.XYZ where @minDate<= GetDate() OR @maxDate >= GetDate(). 

Она возвращает все строки.

+0

Не будет ли это возвращать все строки в базе данных, какими бы ни были даты? – Tobb

+0

«Агрегат может не отображаться в предложении WHERE, если он не находится в подзапросе, содержащемся в предложении HAVING или списке выбора, а агрегированный столбец является внешней ссылкой.« – Tobb

+0

Мы получаем ошибку « Агрегат может не отображаться в предложении WHERE, если он не находится в подзапросе, содержащемся в предложении HAVING или списке выбора, а агрегированный столбец является внешней ссылкой ». user3128590

0
SELECT * 
FROM dbo.Table 
WHERE EndDate >= GETDATE() 
  AND StartDate < DATEADD(DAY, 1, GETDATE()); 

Это будет использовать ваши определенные индексы как можно больше.

Для получения более подробной информации см. bad habits to kick mishandling date range queries (Aaron Bertrand).

+0

Нет вывода вообще – user3128590

+0

Это не имеет смысла. Пожалуйста, предоставьте точный кейс для тестирования. – Jens

0

Попробуйте это, но как сказал Тодд, почему время не включено в выход, если тип данных равен дате?

SELECT * 
FROM dbo.XYZ 
WHERE StartDate <= GETDATE() 
    AND EndDate >= GETDATE() 

EDIT: Похоже, вы сохраняете дату, а не DateTime, поэтому постарайтесь ниже:

SELECT * 
FROM dbo.XYZ 
WHERE StartDate <= CAST(GETDATE() AS DATE) 
    AND EndDate >= CAST(GETDATE() AS DATE) 

EDIT: Не совсем уверен, как еще я могу помочь, вы на SQL Server, Oracle и т.д? Ниже сценария покажет вам, как выглядят типы данных даты и даты и времени (SQL Server), и это меня больше всего сбивает с толку, так как вы утверждаете, что ваш тип данных - это datetime, но вывод выглядит как дата.

SELECT 
cast(GETDATE() as datetime), 
cast(GETDATE() as date) 
+0

Не работает. Мы получаем тот же результат. – user3128590

+0

вы можете запустить ниже и сообщить мне результат, мне нужно проверить, какие данные вы храните : выберите верхний 1 \t GETDATE(), как CurrentDateTime, \t StartDate, \t EndDate из dbo.XYZ – PawelCz

+0

вывод, который вы можете на верхней т.е. второй таблице – user3128590

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