SQL Server дата-час ЛЮБИТЬ вибрати?


92

в MySQL

select * from record where register_date like '2009-10-10%'

Що таке синтаксис у SQL Server?


Що ви насправді хочете перевірити? Що певний час має дату? Або щось інше?
Chris J

1
Здорову дискусію з цього приводу (зокрема про те, чому погано ставитись до DATETIMEтаких значень, як рядки, і чому це може бути погано використовувати BETWEENабо >= AND <=), дивіться у цьому блозі Аарона Бертрана .
Аарон Бертран,

Ваше запитання має щонайменше 5голосів за тег подібного оператора . Чи можу я люб'язно попросити вас запропонувати sql-like як синонім ?
Керміт,

Відповіді:


138

Ви можете використовувати функцію DATEPART ()

SELECT * FROM record 
WHERE  (DATEPART(yy, register_date) = 2009
AND    DATEPART(mm, register_date) = 10
AND    DATEPART(dd, register_date) = 10)

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

AND    DATEPART(hh, register_date) = 12)

отримати записи, зроблені між 12 і 1.

Зверніться до документації MSDN DATEPART для повного списку дійсних аргументів.


Якщо на register_date є індекс, це буде повністю ігнорувати індекс, і продуктивність буде страждати. Можливо, зовсім погано.
Chris J

Гаразд, але це дозволяє уникнути проблеми використання рядкового еквівалента дня після дати, про яку йдеться, що пропонується у декількох відповідях тут. Хитро, коли датою, про яку йде мова, є кінець місяця або року.
Ralph Lavelle

60

Немає прямої підтримки оператора LIKE щодо змінних DATETIME, але ви завжди можете передати DATETIME у VARCHAR:

SELECT (list of fields) FROM YourTable
WHERE CONVERT(VARCHAR(25), register_date, 126) LIKE '2009-10-10%'

Перевірте документи MSDN щоб отримати повний список доступних "стилів" у функції CONVERT.

Марк


1
погодився - але ОП просив спосіб обробляти дату за допомогою LIKE .... Але я згоден - дати дат бажано обробляти в діапазонах, як> = і <= або МІЖ - набагато кращий підхід
marc_s

Всім дякую. На жаль, я просто новачок для SQL.
Paisal

1
Майте на увазі, MSSQL 2012 (я думаю, і старіші версії) перетворить datetime на varchar як '2014-01-06T16: 18: 00.045', тому майте це на увазі, якщо ви також намагаєтесь відповідати годині / хвилині.
balint

Єдине питання, яке я мав із вищезгаданим sql select, це: WHERE CONVERT(VARCHAR(25), register_date, 25) LIKE '2009-10-10%'
Габріель Маріус Попеску

10

Якщо ви це зробите, ви змусите його виконати перетворення рядків. Було б краще побудувати діапазон дат початку / кінця та використовувати:

declare @start datetime, @end datetime
select @start = '2009-10-10', @end = '2009-11-10'
select * from record where register_date >= @start
           and register_date < @end

Це дозволить йому використовувати індекс (якщо такий є register_date), а не сканування таблиці.


Дякую. Вибачте, я просто новачок для SQL.
Paisal,

8

Ви можете використовувати CONVERT, щоб отримати дату в текстовому вигляді. Якщо перетворити його на varchar (10), ви можете використовувати = замість типу:

select *
from record
where CONVERT(VARCHAR(10),register_date,120) = '2009-10-10'

Або ви можете використовувати дату верхньої та нижньої меж, з додатковою перевагою, що вона може використовувати індекс:

select *
from record
where '2009-10-10' <= register_date
and register_date < '2009-10-11'

Я думаю, що в реченні where є помилка, вона повинна бути "де
'10.10.2009

@mr_eclair: не думаю, що це включатиме кожну дату до 11 жовтня
Андомар

7

На жаль, неможливо порівняти дату-час із varchar, використовуючи 'LIKE'. Але бажаний результат можливий іншим способом.

    select * from record where datediff(dd,[record].[register_date],'2009-10-10')=0

3

Ви також можете використовувати convert, щоб зробити дату доступною для пошуку за допомогою LIKE. Наприклад,

select convert(VARCHAR(40),create_date,121) , * from sys.objects where     convert(VARCHAR(40),create_date,121) LIKE '%17:34%'

2

LIKEОператор не працює з датою частин , як місяць або дату , але DATEPARTоператор робить.

Команда, щоб дізнатись усі облікові записи, дата відкриття яких була 1-го:

SELECT * 
  FROM Account 
 WHERE DATEPART(DAY, CAST(OpenDt AS DATE)) = 1`

* КАСТИНГ, OpenDtтому що це цінність, DATETIMEа не просто DATE.


1

Оператор LIKE дуже давно охоплює дати в SQL Server. Він працює лише в американському форматі дати. Як приклад ви можете спробувати:

... WHERE register_date LIKE 'oct 10 2009%'

Я тестував це в SQL Server 2005, і воно працює, але вам дійсно потрібно буде спробувати різні комбінації. Дивні речі, які я помітив:

  • Здається, ви отримуєте все або нічого для різних підполів протягом дати, наприклад, якщо ви шукаєте "apr 2%", ви отримуєте що-небудь лише в 20-х роках - це опускає 2-е.

  • Використання одного підкреслення «_» для представлення одного (підстановочні) характер в повному обсязі роботи, наприклад, WHERE mydate LIKE 'oct _ 2010%'буде НЕ повертати все дати до того 10 - це не повертає нічого, насправді!

  • Формат жорсткий американський: ' mmm dd yyyy hh:mm'

Мені було важко визначити процес на ЛАЙКОВІ секунди, тому, якщо хтось захоче зробити це трохи далі, будьте моїм гостем!

Сподіваюся, це допомагає.


1

Я трохи запізнився з цим потоком, але насправді існує пряма підтримка подібного оператора на сервері MS SQL.

Як задокументовано у довідці LIKE, якщо тип даних не є рядком, його намагаються перетворити на рядок. І як задокументовано в документації cast \ convert:

за замовчуванням перетворення дати і часу в рядок - це тип 0 (, 100), який є мон дд рррр чч: miAM (або PM).

Якщо у вас є така дата в БД:

2015-06-01 11:52:59.057

і ви робите такі запити:

select * from wws_invoice where invdate like 'Jun%'
select * from wws_invoice where invdate like 'Jun 1%'
select * from wws_invoice where invdate like 'Jun 1 %'
select * from wws_invoice where invdate like 'Jun 1 2015:%'
select * from wws_invoice where invdate like 'Jun ? 2015%'
...
select * from wws_invoice where invdate like 'Jun 1 2015 11:52AM'

ви отримаєте цей рядок.

Однак цей формат дати передбачає, що це DateTime2 , тоді в документації сказано:

21 або 121 - ODBC канонічний (з мілісекундами) за замовчуванням для часу, дати, дати-часу2 та зсуву дати-часу. - рррр-мм-дд год год: ми: сс.ммм (24 год)

Це полегшує роботу, і ви можете використовувати:

select * from wws_invoice where invdate like '2015-06-01%'

і отримати запис рахунку-фактури. Ось демонстраційний код:

DECLARE @myDates TABLE (myDate DATETIME2);
INSERT INTO @myDates (myDate)
VALUES
('2015-06-01 11:52:59.057'),
('2015-06-01 11:52:59.054'),
('2015-06-01 13:52:59.057'),
('2015-06-01 14:52:59.057');

SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01%';
SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01 11%';
SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01 11:52:59%';
SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01 11:52:59.054%';

Здійснювати пошук за датою та часом на сервері SQL без будь-якого перетворення в рядок завжди було проблематично. Отримання кожної частини дати є надмірним (що навряд чи буде використовувати індекс). Ймовірно, кращим способом, коли ви не використовуєте перетворення рядків, було б використовувати перевірку діапазону. тобто:

select * from record 
where register_date >= '20091010' and register_date < '20091011';

1

Спробуйте це

SELECT top 10 * from record WHERE  IsActive = 1 and CONVERT(VARCHAR, register_date, 120) LIKE '2020-01%'

0

Я так вирішив свою проблему. Дякуємо за пропозиції щодо вдосконалення. Приклад у C #.

string dd, mm, aa, trc, data;
dd = nData.Text.Substring(0, 2);
mm = nData.Text.Substring(3, 2);
aa = nData.Text.Substring(6, 4);
trc = "-";
data = aa + trc + mm + trc + dd;

"Select * From bdPedidos Where Data Like '%" + data + "%'";
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.