Как запросить поле 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 апреля 2014 года или 19 марта 2015 года, поскольку «дневная» часть этих дат одинакова (и я видел отчеты в другом месте, что это было бы действовать таким образом), но я протестировал его на базе данных, и, похоже, он работает правильно.
mono código

Да, потому что DateDiff()функция во всех ее вариантах вычисляет и возвращает количество границ дат, которые необходимо пересечь, чтобы перейти от одной даты к другой. Вот почему DateDiff(day, '1Jan2016', '31Dec2017 23:259:59')и DateDiff(day, '31Dec2016 23:259:59', '1Jan2017 ') оба возвращаются 1.
Чарльз Бретана

55

Простой ответ;

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

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


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'))

- Для даты значение «нарезано». - Для datetime значение округляется до следующей даты. (Ближайшее значение). - Для datetime2 значение точное.


7

Это работает для меня для сервера MS SQL:

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


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 06

Это не работает, потому что «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.