Як запитати поле DATETIME, використовуючи лише дату в Microsoft SQL Server?


88

У мене є таблиця TEST з DATETIMEполем, наприклад:

ID NAME DATE
1 TESTING 2014-03-19 20:05:20.000

Що мені потрібно для запиту, що повертає цей рядок і кожен рядок із датою 19.03.2014, незалежно від часу. Я спробував використовувати

select * from test where date = '03/19/2014';

Але він не повертає рядків. Єдиний спосіб змусити це працювати, який я знайшов, - це також вказати часову частину дати:

select * from test where date = '03/19/2014 20:03:02.000';

Відповіді:


126

використовувати діапазон або функцію DateDiff

 select * from test 
 where date between '03/19/2014' and '03/19/2014 23:59:59'

або

 select * from test 
 where datediff(day, date, '03/19/2014') = 0

Інші варіанти:

  1. Якщо у вас є контроль над схемою бази даних і вам не потрібні дані часу, вийміть їх.

  2. або, якщо вам потрібно його зберегти, додайте обчислюваний атрибут стовпця, який має часову частину значення дати, позбавлену ...

Alter table Test Add DateOnly As DateAdd(day, datediff(day, 0, date), 0)

або, в більш пізніх версіях SQL Server ...

Alter table Test Add DateOnly As Cast(DateAdd(day, datediff(day, 0, date), 0) as Date)

тоді ви можете написати свій запит так просто:

select * from test 
where DateOnly = '03/19/2014'

Добре, це працює, але мені було цікаво, чи є якийсь простіший спосіб.
delphirules

Ну, єдиний інший простіший спосіб - це не помістити дані часу в базу даних спочатку ... або створити обчислюваний атрибут, який позбавляє часову частину і використовує його ... Я додав обидва варіанти до своєї відповіді.
Чарльз Бретана

Я був стурбований тим, що метод DATEDIFF поверне істину (небажано) для таких дат, як 19.04.2014 або 19.03.2015, оскільки "денна" частина цих дат однакова (і в інших місцях я бачив повідомлення про те, що діяти таким чином), але я протестував його на базі даних, і, здається, він працює правильно.
mono código

Так, оскільки DateDiff()функція, у всіх своїх варіантах, обчислює і повертає кількість меж дати, які необхідно перетнути, щоб отримати frlom одну дату до іншої. Ось чому DateDiff(day, '1Jan2016', '31Dec2017 23:259:59')і DateDiff(day, '31Dec2016 23:259:59', '1Jan2017 ') обидва повертаються 1.
Charles Bretana

55

Проста відповідь;

select * from test where cast ([date] as date) = '03/19/2014';

Хоча це правильна відповідь, я хочу зазначити, що розміщення поля дати, яке оцінює будь-яку функцію, призведе до проблем із продуктивністю. Будь-який індекс дати буде марним, і двигун повинен буде оцінити кожен рядок
jean


7
select * from test 
where date between '03/19/2014' and '03/19/2014 23:59:59'

Це справді погана відповідь. З двох причин.

1. Що відбувається з такими часами, як 23.59.59.700 і т. Д. Є часи, більші за 23:59:59 та наступний день.

2. Поведінка залежить від типу даних. Запит поводиться по-різному для типів datetime / date / datetime2.

Тестування з 23: 59: 59.999 робить це ще гіршим, оскільки залежно від типу дати ви отримуєте різні округлення.

select convert (varchar(40),convert(date      , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime  , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime2 , '2014-03-19 23:59:59.999'))

- Для дати значення "нарізане". - Для дати і часу значення округлюється до наступної дати. (Найближче значення). - Для datetime2 значення є точним.


7

Це працює для мене на сервері MS SQL:

select * from test
where 
year(date) = 2015
and month(date) = 10
and day(date)= 28 ;

1

Спробуйте це

 select * from test where Convert(varchar, date,111)= '03/19/2014'

1

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

select * from test where DATEADD(dd, 0, DATEDIFF(dd, 0, date)) = '03/19/2014';

1
Дякую, але я думаю, що простішим рішенням було б порівняння з часом, як і попереднє рішення.
delphirules

0

Ви можете використовувати такий підхід, який скорочує часову частину:

select * from test
where convert(datetime,'03/19/2014',102) = DATEADD(dd, DATEDIFF(dd, 0, date), 0)

0
-- Reverse the date format
-- this false:
    select * from test where date = '28/10/2015'
-- this true:
    select * from test where date = '2015/10/28'

1
Будь ласка, додайте пояснення до своєї відповіді!
ρss

Це не працює, оскільки "2015/10/28 00: 00.001" відрізняється від "2015/10/28"
PedroC88,

0

Просто використовуйте це у своєму WHEREреченні.

Частина "SubmitDate" нижче - це назва стовпця, тому вставте свою.

Це поверне лише частину результатів "Рік", не враховуючи хвилини тощо.

Where datepart(year, SubmitDate) = '2017'

0
select *, cast ([col1] as date) <name of the column> from test where date = 'mm/dd/yyyy'

"col1" - це назва стовпця з датою та часом
<назва стовпця> тут ви можете змінити назву за бажанням


0
select *
  from invoice
 where TRUNC(created_date) <=TRUNC(to_date('04-MAR-18 15:00:00','dd-mon-yy hh24:mi:ss'));

0

Існує проблема з датами та мовами, і щоб уникнути її, потрібно запитати дати у такому форматі РРРРММДД.

Цей спосіб нижче повинен бути найшвидшим за посиланням нижче. Я перевірив SQL Server 2012 і погоджуюсь із посиланням.

select * from test where date >= '20141903' AND date < DATEADD(DAY, 1, '20141903');

0

використовуй це

select * from TableName where DateTimeField > date() and  DateTimeField < date() + 1

-1

Перевірте цей запит.

SELECT *,DATE(chat_reg_date) AS is_date,TIME(chat_reg_time) AS is_time FROM chat WHERE chat_inbox_key='$chat_key' 
                         ORDER BY is_date DESC, is_time DESC

-1
select * from invoice where TRANS_DATE_D>= to_date  ('20170831115959','YYYYMMDDHH24MISS')
and TRANS_DATE_D<= to_date  ('20171031115959','YYYYMMDDHH24MISS');

Я думаю, що це синтаксис Oracle, не працює на сервері sql
ceinmart

-2
SELECT * FROM test where DATEPART(year,[TIMESTAMP]) = '2018'  and  DATEPART(day,[TIMESTAMP]) = '16' and  DATEPART(month,[TIMESTAMP]) = '11'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.