SQL Server datetime НРАВИТСЯ выбрать?

92

в MySQL

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

Каков синтаксис в SQL Server?

Paisal
источник
Что вы на самом деле хотите проверить? Что данное datetime имеет заданную часть даты? Или что-то другое?
Крис Дж,
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, он полностью проигнорирует индекс, и производительность пострадает. Наверное, совсем плохо.
Крис Дж,
Хорошо, но это позволяет избежать проблемы использования строкового эквивалента дня после рассматриваемой даты, что предлагается здесь в нескольких ответах. Сложно, когда рассматриваемая дата является концом месяца или года.
Ральф Лавель,
60

Нет прямой поддержки оператора LIKE для переменных DATETIME, но вы всегда можете преобразовать DATETIME в VARCHAR:

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

Проверьте документы MSDN для получения полного списка доступных «стилей» в функции CONVERT.

Марк

marc_s
источник
1
согласился - но OP запросил способ обработки даты и времени с помощью LIKE .... Но я согласен - время предпочтительно обрабатывать с диапазонами, такими как> = и <= или BETWEEN - гораздо лучший подход
marc_s
Всем спасибо. Извините, я новичок в SQL.
Paisal
1
Имейте в виду, что MSSQL 2012 (я думаю, что и более старые версии) преобразует datetime в varchar как '2014-01-06T16: 18: 00.045', поэтому имейте это в виду, если вы попытаетесь сопоставить час / минуту.
Балинт
Единственная проблема, с которой я столкнулся с указанным выше выбором sql, заключается в следующем: 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), вы можете использовать = вместо like:

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'
Андомар
источник
Я думаю, что в предложении
Вишванат
@mr_eclair: не думаю, это будет включать каждое свидание до 11 октября
Андомар,
8

К сожалению, невозможно сравнить datetime с 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.

Мохит Сарин
источник
2

Попробуй это

SELECT top 10 * from record WHERE  IsActive = 1 and CONVERT(VARCHAR, register_date, 120) LIKE '2020-01%'
рок
источник
1

Оператор LIKE для дат в SQL Server очень ненадежен. Работает только с американским форматом даты. В качестве примера вы можете попробовать:

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

Я тестировал это в SQL Server 2005, и он работает, но вам действительно нужно попробовать разные комбинации. Я заметил следующие странные вещи:

  • Кажется, вы получаете только все или ничего для разных подполей в пределах даты, например, если вы ищете «апр 2%», вы получаете только 20-е число - оно пропускает 2-е.

  • Использование одного подчеркивания «_» для представления одного (подстановочные) характер не полностью работы, например, WHERE mydate LIKE 'oct _ 2010%'будет не возвращать все даты до того того 10 - это не возвращает ничего, на самом деле!

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

Мне было трудно описать процесс за несколько секунд, так что если кто-то хочет пойти дальше, будь моим гостем!

Надеюсь это поможет.

Павел
источник
1

Я немного опоздал в эту ветку, но на самом деле есть прямая поддержка подобного оператора в сервере MS SQL.

Как описано в справке LIKE, если тип данных не является строкой, выполняется попытка преобразовать его в строку. И как описано в документации cast \ convert:

преобразование даты и времени по умолчанию в строку - это тип 0 (, 100), то есть mon dd yyyy hh: 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 для времени, даты, datetime2 и datetimeoffset. - гггг-мм-дд чч: ми: сс.ммм (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';
Цетин Басоз
источник
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 + "%'";
Эронильдо Барбоза
источник