Select * from [User] U
where U.DateCreated = '2014-02-07'
але в базі даних користувач був створений на 2014-02-07 12:30:47.220
і коли я лише помістив'2014-02-07'
Він не відображає жодних даних
Відповіді:
НЕ спокушайтеся робити такі речі:
Select * from [User] U where convert(varchar(10),U.DateCreated, 120) = '2014-02-07'
Це кращий спосіб:
Select * from [User] U
where U.DateCreated >= '2014-02-07' and U.DateCreated < dateadd(day,1,'2014-02-07')
див .: Що насправді означає слово “SARGable”?
EDIT + Є дві основні причини для уникнення використання функцій на даних у реченні where (або в умовах об'єднання).
2014-02-07
. Набагато ефективніше змінювати критерії відповідно до даних."Внесення змін до критеріїв відповідно до даних" - це мій спосіб описати "використання SARGABLE
предикатів"
І не використовуйте між ними.
найкраща практика з діапазонами дат та часу - уникати МІЖ і завжди використовувати форму:
WHERE col> = '20120101' AND col <'20120201' Ця форма працює з усіма типами та з усіма точностями, незалежно від того, чи застосовується часова частина.
http://sqlmag.com/t-sql/t-sql-best-practices-part-2 (Іцік Бен-Ган)
can
іноді компенсують.
date literal
формат - "РРРРММДД". Типи даних: дата чи дата чи час, або час, або дата і час2 або невеликий час НЕ мають формату, оскільки вони зберігаються як числа. Для літералів дати `` РРРР-ММ-ДД '' НЕ цілком безпечно існує один параметр мови, який може неправильно інтерпретувати цю послідовність як РРРР-ДД-ММ
Якщо ви використовуєте SQL Server 2008 або пізнішої версії, ви можете використовувати тип даних date:
SELECT *
FROM [User] U
WHERE CAST(U.DateCreated as DATE) = '2014-02-07'
Слід зазначити, що якщо стовпець дати індексується, тоді він все одно використовуватиме індекс і може бути SARGable. Це особливий випадок для дат та часу.
Ви бачите, що SQL Server насправді перетворює це на пропозиції> та <:
Я щойно спробував це на великій таблиці, із вторинним індексом у стовпці дати відповідно до коментарів @ kobik, і індекс все ще використовується, це не стосується прикладів, які використовують BETWEEN або> = і <:
SELECT *
FROM [User] U
WHERE CAST(U.DateCreated as DATE) = '2016-07-05'
AaronsBad
база даних?
Відповідно до вашого запиту
Select * from [User] U where U.DateCreated = '2014-02-07'
SQL Server порівнює точну дату та час, тобто (порівняння 2014-02-07 12:30:47.220
з2014-02-07 00:00:00.000
для рівності). тому результат порівняння хибний
Тому, порівнюючи дати, потрібно враховувати і час. Можна використовувати
Select * from [User] U where U.DateCreated BETWEEN '2014-02-07' AND '2014-02-08'
.
between
з рівними на обох кінцях (> = і <=), наприклад, select * from x where col_1 between 'A' and 'M'
включає A і M (плюс B до L, звичайно). Цей інклюзивний характер between
є приголомшливим для чогось на зразок покажчика документів; але для діапазонів дати / часу це катастрофа, оскільки створює перекриття. Я знаю, що використання між виглядає чудово, але насправді SQL between
просто не працює належним чином для діапазонів дат. Завжди використовуйте комбінацію> = з <як уU.DateCreated >='2014-02-07' and U.DateCreated < '2014-02-08'
between
це нормально. Ваша пропозиція використовувати, >=
і <
, безсумнівно, є кращою between
для діапазонів дат. Я просто хочу сказати, що ми повинні враховувати час і коли порівнюємо дати.
Будь ласка, спробуйте це. Цей запит може бути використаний для порівняння дат
select * from [User] U where convert(varchar(10),U.DateCreated, 120) = '2014-02-07'
Ви можете використовувати LIKE
оператор замість =
. Але щоб зробити це за допомогою DateStamp, потрібно CONVERT
спочатку до VARCHAR:
SELECT *
FROM [User] U
WHERE CONVERT(VARCHAR, U.DateCreated, 120) LIKE '2014-02-07%'