简体   繁体   English

SQL Server 日期时间 LIKE 选择?

[英]SQL Server datetime LIKE select?

in MySQL在 MySQL 中

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

What is the syntax in SQL Server? SQL Server 中的语法是什么?

You could use the DATEPART() function您可以使用 DATEPART() 函数

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

I find this way easy to read, as it ignores the time component, and you don't have to use the next day's date to restrict your selection.我发现这种方式易于阅读,因为它忽略了时间部分,而且您不必使用第二天的日期来限制您的选择。 You can go to greater or lesser granularity by adding extra clauses, using the appropriate DatePart code, eg您可以通过添加额外的子句,使用适当的 DatePart 代码来更大或更小的粒度,例如

AND    DATEPART(hh, register_date) = 12)

to get records made between 12 and 1.获取 12 到 1 之间的记录。

Consult the MSDN DATEPART docs for the full list of valid arguments.有关有效参数的完整列表,请参阅MSDN DATEPART 文档

There's no direct support for LIKE operator against DATETIME variables, but you can always cast the DATETIME to a VARCHAR:对 DATETIME 变量的 LIKE 运算符没有直接支持,但您始终可以将 DATETIME 转换为 VARCHAR:

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

Check the MSDN docs for a complete list of available "styles" in the CONVERT function.查看MSDN 文档以获取 CONVERT 函数中可用“样式”的完整列表。

Marc马克

If you do that, you are forcing it to do a string conversion.如果你这样做,你是在强迫它做一个字符串转换。 It would be better to build a start/end date range, and use:最好建立一个开始/结束日期范围,并使用:

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

This will allow it to use the index (if there is one on register_date ), rather than a table scan.这将允许它使用索引(如果register_date上有索引),而不是表扫描。

You can use CONVERT to get the date in text form.您可以使用 CONVERT 以文本形式获取日期。 If you convert it to a varchar(10), you can use = instead of like:如果将其转换为 varchar(10),则可以使用 = 而不是 like:

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

Or you can use an upper and lower boundary date, with the added advantage that it could make use of an index:或者您可以使用上限和下限日期,还有一个额外的优势,那就是它可以使用索引:

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

不幸的是,无法使用“LIKE”将日期时间与 varchar 进行比较,但可以通过另一种方式获得所需的输出。

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

试试这个

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

You can also use convert to make the date searchable using LIKE.您还可以使用 convert 使日期可使用 LIKE 进行搜索。 For example,例如,

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

The LIKE operator does not work with date parts like month or date but the DATEPART operator does. LIKE运算符不适用于月份或日期等日期部分,但DATEPART运算符可以。

Command to find out all accounts whose Open Date was on the 1st:找出所有开户日期为 1 日的账户的命令:

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

*CASTING OpenDt because it's value is in DATETIME and not just DATE . *CASTING OpenDt因为它的值在DATETIME而不仅仅是DATE

I am a little late to this thread but in fact there is direct support for the like operator in MS SQL server.我对这个线程有点晚了,但实际上在 MS SQL 服务器中有对 like 运算符的直接支持。

As documented in LIKE help if the datatype is not a string it is attempted to convert it to a string.如 LIKE 帮助中所述,如果数据类型不是字符串,则尝试将其转换为字符串。 And as documented in cast\\convert documentation:正如 cast\\convert 文档中所述:

default datetime conversion to string is type 0 (,100) which is mon dd yyyy hh:miAM (or PM).默认日期时间转换为字符串类型 0 (,100),即 mon dd yyyy hh:miAM(或 PM)。

If you have a date like this in the DB:如果您在数据库中有这样的日期:

2015-06-01 11:52:59.057

and you do queries like this:你做这样的查询:

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'

you get that row.你得到那一行。

However, this date format suggests that it is a DateTime2 , then documentation says:但是,这种日期格式表明它是DateTime2 ,然后文档说:

21 or 121 -- ODBC canonical (with milliseconds) default for time, date, datetime2, and datetimeoffset. 21 或 121 -- 时间、日期、datetime2 和 datetimeoffset 的 ODBC 规范(以毫秒为单位)默认值。 -- yyyy-mm-dd hh:mi:ss.mmm(24h) -- yyyy-mm-dd hh:mi:ss.mmm(24h)

That makes it easier and you can use:这使它更容易,您可以使用:

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

and get the invoice record.并获取发票记录。 Here is a demo code:这是一个演示代码:

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%';

Doing datetime searches in SQL server without any conversion to string has always been problematic.在 SQL Server 中进行日期时间搜索而不进行任何字符串转换一直是有问题的。 Getting each date part is an overkill (which unlikely would use an index).获取每个日期部分是一种矫枉过正(不太可能使用索引)。 Probably a better way when you don't use string conversion would be to use range checks.当您不使用字符串转换时,可能更好的方法是使用范围检查。 ie: IE:

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

There is a very flaky coverage of the LIKE operator for dates in SQL Server.对于 SQL Server 中的日期,LIKE 运算符的覆盖范围非常有限。 It only works using American date format.它仅适用于美国日期格式。 As an example you could try:例如,您可以尝试:

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

I've tested this in SQL Server 2005 and it works, but you'll really need to try different combinations.我已经在 SQL Server 2005 中对此进行了测试并且它可以工作,但是您确实需要尝试不同的组合。 Odd things I have noticed are:我注意到的奇怪的事情是:

  • You only seem to get all or nothing for different sub fields within the date, for instance, if you search for 'apr 2%' you only get anything in the 20th's - it omits 2nd's.您似乎只能获得日期内不同子字段的全部或全部信息,例如,如果您搜索“apr 2%”,您只会得到 20 日的任何内容 - 它省略了 2 日。

  • Using a single underscore '_' to represent a single (wildcard) character does not wholly work, for instance, WHERE mydate LIKE 'oct _ 2010%' will not return all dates before the 10th - it returns nothing at all, in fact!使用单个下划线 '_' 来表示单个(通配符)字符并不完全有效,例如, WHERE mydate LIKE 'oct _ 2010%'不会返回 10 号之前的所有日期 - 事实上它根本不返回任何内容!

  • The format is rigid American: ' mmm dd yyyy hh:mm '格式是严格的美国:' mmm dd yyyy hh:mm '

I have found it difficult to nail down a process for LIKEing seconds, so if anyone wants to take this a bit further, be my guest!我发现很难在 LIKE 秒内确定一个过程,所以如果有人想更进一步,请成为我的客人!

Hope this helps.希望这可以帮助。

I solved my problem that way.我就是这样解决了我的问题。 Thank you for suggestions for improvements.感谢您提出改进建议。 Example in C#. 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 + "%'";

I realise this an old question, but a lot of the answers here don't give a SARGable answer here, nor cover parmetrisation.我意识到这是一个古老的问题,但这里的很多答案都没有给出一个可搜索的答案,也没有涵盖参数化。

First off, you are far better off using >= and < logic.首先,您最好使用>=<逻辑。 For the date you want, then that would look like this:对于您想要的日期,则如下所示:

SELECT {Your Columns}
FROM dbo.record
WHERE register_date >= '20091010'
  AND register_date < '20091011';

This'll include every time value on 2009-10-10, including the stroke of midnight on the day, and a nanosecond prior to 2009-10-11.这将包括 2009 年 10 月 10 日的每个时间值,包括当天午夜和 2009 年 10 月 11 日之前的纳秒。

Often, however, you'll be parametrising your query, so instead what you can do is use DATEADD to add a day to the second clause:但是,您通常会对查询进行参数化,因此您可以使用DATEADD为第二个子句添加一天:

DECLARE @DateParam date = '20091010';

SELECT {Your Columns}
FROM dbo.record
WHERE register_date >= @DateParam
  AND register_date < DATEADD(DAY,1,@DateParam);

This maintains SARGability and means that any indexes on register_date can be used.这维护了 SARGability 并意味着可以使用register_date上的任何索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM