SQL-запит для вибору дати між двома датами


303

У мене є start_dateі end_date. Я хочу отримати список дат між цими двома датами. Хто-небудь може мені допомогти вказати на помилку мого запиту.

select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and Date between 2011/02/25 and 2011/02/27

Ось Dateце datetimeзмінна.

Відповіді:


484

ви повинні помістити ці дві дати між окремими цитатами, як ..

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date between '2011/02/25' and '2011/02/27'

або може використовувати

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date >= '2011/02/25' and Date <= '2011/02/27'

майте на увазі, що перше побачення включно, але друге - ексклюзивне, оскільки воно фактично є "2011/02/27 00:00:00"


42
SQL Server за замовчуванням дату без часу до 00:00:00. Тож чи не повернеться цей запит нічого з 2011/02/25 та 2011/02/26 опівночі?
Метт

5
@Deepak, ваш другий біт повинен сказати> = і <=
IndoKnight

3
Ви можете згадати, що порядок має значення у функції МЕЖ. Він має йти від найдавнішого зліва та більш недавнього праворуч. Це неінтуїтивно, оскільки = є порівняльним оператором у sql та працює як для "EmployeeII = 1", так і для "1 = EmployeeII" у пункті "де".
Fi Horan

@Matt, згідно з документацією між ними , якщо рядок мав дату 2011/02/27 без часу, то цей рядок еквівалентний даті 2011/02/27 00:00 і повертався б у запит, оскільки він менший або рівний 2011/02/27 00:00. Тож якщо ви не маєте справу з часом, betweenпрацюйте як слід.
timctran

@timctran Право, але 2011/02/27 00:00 - це те, що ми би називали опівночі 2011/02/26. Імовірно, запит означає включити 27-е місце у набір результатів - але запис із часовою позначкою 2011/02/27 5:00 не буде включений.
Сінджай

128

Оскільки час дати без визначеного часового відрізка матиме значення date 00:00:00.000, якщо ви хочете бути впевненим, що ви отримаєте всі дати у своєму діапазоні, ви повинні або вказати час для своєї дати закінчення, або збільшити дату закінчення та використовувати <.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/27 23:59:59.999'

АБО

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date < '2011/02/28'

АБО

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date <= '2011/02/27 23:59:59.999'

НЕ використовуйте наступне, оскільки це може повернути деякі записи з 2011/02/28, якщо їх час 00: 00: 00.000.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/28'

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

3
Ваша відповідь мені дуже допомогла, @WelshDragon - Інші відповіді виключали той факт, що формат дати повинен бути "простою датою" на сервері, щоб ігнорувати години. "<= END_DATE" передбачає 12 ранку, про що я не знав. Я виконував запит із написом "... <= 01.01.2014", і я не міг зрозуміти, чому замовлення на цю дату не відображаються для 1-го. Дуже дякую.
Кіт

@WelshDragon - ваша відповідь є дуже хорошим матеріалом для використання дат, як і де застереження. Дякую
Джек Мороз

Що не так, якщо він повернеться '2011/02/28 00:00:00.000'?
Муфлікс

1
Спробувавши це сьогодні, ви також можете користуватися convert(date, Date) between '2011/02/25' and '2011/02/27'(принаймні, з недавнім MS SQL Server). convert()Частина дбатиме про позбавивши частину часу і між порівняння буде працювати , як очікувалося.
сенсей

14

Спробуйте це:

select Date,TotalAllowance from Calculation where EmployeeId=1
             and [Date] between '2011/02/25' and '2011/02/27'

Значення дати потрібно вводити як рядки.

Щоб забезпечити надійність подальшого запиту для SQL Server 2008 і новіших Dateверсій , слід уникати, оскільки це зарезервоване слово в пізніших версіях.

Майте на увазі, що дати без разів беруть опівночі як свої значення за замовчуванням, тому ви, можливо, не маєте там правильного значення.


1
Дата не є ключовим словом і її не потрібно уникати. Підсвічування синтаксису - це лише підсвічування синтаксису, ключові слова потрібно уникати, лише якщо вони викликають синтаксичну помилку. Також є хорошою практикою використовувати явну конверсію замість неявного перетворення датестуючих констант. - і дата між CAST ('2011/02 / 25'AS DATETIME) та CAST (' 2011/02 / 27'AS DATETIME)
tponthieux,

5
Звичайно, ви праві, якщо це SQL Server 2005, який позначає ОП. Однак Дата зарезервована у 2008 році і вище, тому для підтвердження майбутнім ніякої шкоди уникнути цього немає. Я відредагував свою відповідь.

1
Якщо він вказав би єдину дату для обох, вона поверне нульові рядки, але я думаю, що це не вимога
опції

12
select * from table_name where col_Date between '2011/02/25' 
AND DATEADD(s,-1,DATEADD(d,1,'2011/02/27'))

Тут спочатку додайте день до поточного endDate, він буде 2011-02-28 00:00:00, потім ви віднімаєте одну секунду, щоб зробити кінцеву дату 2011-02-27 23:59:59. Роблячи це, ви можете отримати всі дати між заданими інтервалами.

output:
2011/02/25
2011/02/26
2011/02/27


5

Цей запит добре підходить для отримання значень між поточною датою та наступними 3 датами

SELECT * FROM tableName  WHERE columName 
BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)

Це з часом додасть додаткові 3 дні буфера до поточної дати.


5

Це дуже давно, але враховуючи багато досвіду, який я мав з датами, ви можете розглянути це: Люди використовують різні регіональні налаштування, як такі, деякі люди (і деякі бази даних / комп'ютери, залежно від регіональних налаштувань) можуть читати це дата 11.12.2016 як 11 грудня 2016 або 12 листопада 2016 року. Більше того, 16/11/12, що постачається в базу даних MySQL, буде внутрішньо перетворений до 12 листопада 2016 року, тоді як база даних Access, що працює на комп'ютері з регіональними налаштуваннями Великобританії, буде інтерпретувати та зберігати його як 16 листопада 2012 року

Тому я зробив свою політику чіткою, коли я збираюся взаємодіяти з датами та базами даних. Тому я завжди надаю свої запити та коди програмування наступним чином:

SELECT FirstName FROM Students WHERE DoB >= '11 Dec 2016';

Зауважте також, що Access прийме #, таким чином:

SELECT FirstName FROM Students WHERE DoB >= #11 Dec 2016#;

але MS SQL сервер не буде, тому я завжди використовую "" ", як зазначено вище, що обидві бази даних приймають.

І отримуючи цю дату зі змінної в коді, я завжди конвертую результат у рядок наступним чином:

"SELECT FirstName FROM Students WHERE DoB >= " & myDate.ToString("d MMM yyyy")

Я пишу це, тому що я знаю, що іноді деякі програмісти можуть не бути достатньо захопленими, щоб виявити притаманне перетворення. Не буде помилок для дат <13, просто різні результати!

Що стосується заданого питання, додайте один день до останньої дати та проведіть порівняння наступним чином:

dated >= '11 Nov 2016' AND dated < '15 Nov 2016' 

Ваша інформація допомогла виконати моє завдання. я працював над цим більше 10 годин, і не відповіді відповідатимуть на мене. Коли я об'єднуюся, як ти показав, мій проект чудово працює. але, здається, правило не писати такий SQL-оператор. коли я намагаюся встановити SqlCommand для додавання параметрів дати до оператора SQL, параметри не будуть додаватися, і я отримаю помилку, яку я повинен оголосити "@startDate" і "@endDate". я не можу пройти це питання. Я спробував ваш формат дати "dd MMM yyyy", який працював, і я також спробував "yyyy MMM dd", який також виконував те саме.
Дейв Гампель

Чудово це допомогло! Вище наведені зразки коду. Завжди краще оголошувати та використовувати параметри, щоб уникнути ін'єкції SQL. І, здається, вас вже вимагають / захищають правила у вашому проекті, що добре.
Ганнінгтон Мамбо

4
select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and convert(varchar(10),Date,111) between '2011/02/25' and '2011/02/27'

3

Спробуйте вказати дати між # #, наприклад:

#2013/4/4# and #2013/4/20#

Це працювало для мене.


1
Що # робить у цьому контексті?
BK

@BK - це роздільник, як лапки для рядків. "Подаючи значення для оператора SQL, наприклад, як критерії запиту, тип їх даних повинен бути правильно визначений" класифікатором ". Це робиться шляхом додавання значення між парою відповідних символів." посилання -> посилання
Олександр

1
@BK Якщо це синтаксис TSql, вам потрібно буде використовувати одинарні лапки ( ' ), щоб отримати те, що вам потрібно. посилання * основи sql-fontstuff.com * Початок SQL - Пол Вілтон, Джон Колбі
Олександр

1
Не може бути більш зрозумілим, що питання стосується SQL Server і T-SQL. T-SQL та SQL Server не приймають дати між хеш-тегами, він приймає дати між окремими котируваннями. Ця відповідь неправильна.
ТТ.

@TT. кількість звернень говорить про те, що це все-таки комусь допомогло. У той час, коли я писав свою відповідь, прийняту відповідь вже було обрано. Все-таки я написав це, щоб допомогти всім, хто може приїхати сюди з Google чи десь ще :)
Олександр

2

якщо його дата через 24 години, а починається вранці і закінчується вночі, слід додати щось на кшталт:

declare @Approval_date datetime
set @Approval_date =getdate()
Approval_date between @Approval_date +' 00:00:00.000' and @Approval_date +' 23:59:59.999'

1

найкращий запит на дату вибору між поточною датою і назад три дні :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN       
DATE_SUB(CURDATE(), INTERVAL 3 DAY)  AND CURDATE() 

найкращий запит на дату вибору між поточною датою та наступними трьома днями :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN   
   CURDATE()  AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)   

1

Перевірте нижче Приклади: Працюючі та неробочі.

select * from tblUser Where    
convert(varchar(10),CreatedDate,111) between '2015/04/01' and '2016/04/01' //--**Working**

АБО

select * from tblUser Where
(CAST(CreatedDate AS DATETIME) between CAST('2015/04/01' AS DATETIME) And CAST('2016/4/30'AS DATETIME)) //--**Working**

АБО

select * from tblUser Where
(YEAR(CreatedDate) between YEAR('2015/04/01') And YEAR('2016/4/30')) 
//--**Working**

І нижче не працює:

select * from tblUser Where
Convert(Varchar(10),CreatedDate,111) >=  Convert(Varchar(10),'01-01-2015',111) and  Convert(Varchar(10),CreatedDate,111) <= Convert(Varchar(10),'31-12-2015',111) //--**Not Working**


select * from tblUser Where
(Convert(Varchar(10),CreatedDate,111) between Convert(Varchar(10),'01-01-2015',111) And Convert(Varchar(10),'31-12-2015',111)) //--**Not Working**

1

ми можемо використовувати між, щоб показати дані двох дат, але це буде шукати всі дані та порівнювати, так це зробить наш процес повільним для величезних даних, тому я пропоную всім використовувати datediff:

qry = "SELECT * FROM [calender] WHERE datediff(day,'" & dt & "',[date])>=0 and datediff(day,'" & dt2 & "',[date])<=0 "

тут календарем є Таблиця, dt як змінна дата початку, а dt2 - змінна дата завершення.


0

Мені подобається використовувати синтаксис "1 місяць ім'я 2015" для дат, наприклад:

   WHERE aa.AuditDate>='1 September 2015'
     AND aa.AuditDate<='30 September 2015'

на дати


0

Я б пішов на

select Date,TotalAllowance from Calculation where EmployeeId=1
             and Date >= '2011/02/25' and Date < DATEADD(d, 1, '2011/02/27')

Логіка полягає в тому, що >=включає всю дату початку і <виключає дату закінчення, тому ми додаємо одну одиницю до кінцевої дати. Це може адаптуватися місяцями, наприклад:

select Date, ... from ...
             where Date >= $start_month_day_1 and Date < DATEADD(m, 1, $end_month_day_1)


0

Ви можете спробувати цей SQL

select * from employee where rec_date between '2017-09-01' and '2017-09-11' 


0
/****** Script for SelectTopNRows command from SSMS  ******/
SELECT TOP 10 [Id]
  ,[Id_parvandeh]
  ,[FirstName]
  ,[LastName]
  ,[RegDate]
  ,[Gilder]
  ,[Nationality]
  ,[Educ]
  ,[PhoneNumber]
  ,[DueInMashhad]

  ,[EzdevajDate]


  ,[MarriageStatus]
  ,[Gender]
  ,[Photo]

  ,[ModifiedOn]
  ,[CreatorIp]
   From
  [dbo].[Socials] where educ >= 3 or EzdevajDate  >= '1992/03/31' and EzdevajDate <= '2019/03/09' and MarriageStatus = 1

-2

краще написати так:

CREATE PROCEDURE dbo.Get_Data_By_Dates
(
    @EmployeeId INT = 1,
    @Start_Date DATE,
    @End_Date Date
)
AS
Select * FROM Calculation  
    where EmployeeId=@EmployeeId AND Test_Date BETWEEN @Start_Date AND @End_Date
RETURN

1
Використання збереженої процедури в цій ситуації не матиме сенсу, оскільки це жахливо знизить гнучкість запиту SQL, він буде настільки специфічним, якщо ви не хочете використовувати його в дійсно конкретній ситуації, будь ласка, не використовуйте Збережена процедура - також існує багато вдосконалень для вашої збереженої процедури, і ви можете їх знайти у цій спільноті;).
shA.t

-6
SELECT Date, TotalAllowance  
FROM Calculation  
WHERE EmployeeId = 1 
  AND Date BETWEEN to_date('2011/02/25','yyyy-mm-dd') 
               AND to_date ('2011/02/27','yyyy-mm-dd');

1
Ви, напевно, думали про Oracle SQL, коли писали цю відповідь. Це дійсно в Oracle. Не так багато в SQL Server (з того, що я бачу).
Чарльз Колдвелл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.