SQL Server datetime喜欢吗?


92

在MySQL中

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

SQL Server的语法是什么?


您实际上要检查什么?给定日期时间是否有给定日期部分?或者是其他东西?
克里斯J

1
有关此问题的健康讨论(包括为什么DATETIME像字符串那样对待值不好,以及为什么使用BETWEENor 不好>= AND <=),请参阅Aaron Bertrand的博客
亚伦·伯特兰

您的问题至少5like-operator标签具有投票权。我可以请您建议像sql这样同义词吗?
柯米特(Kermit)2013年

Answers:


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上有一个索引,则将完全忽略该索引,从而降低性能。可能非常糟糕。
克里斯J

好的,但是它确实避免了使用有关日期之后的第二天的等效字符串的问题,在此处的一些答案中建议使用该字符串。棘手的问题日期是月份或年份的结尾。
拉尔夫·拉维尔2009年

59

对于DATETIME变量,没有直接支持LIKE运算符,但是您始终可以将DATETIME强制转换为VARCHAR:

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

检查MSDN文档以获取CONVERT函数中可用“样式”的完整列表。

马克


1
同意-但OP请求一种与LIKE一起处理日期时间的方法。...但是我同意-最好使用> =和<=或BETWEEN之类的范围来处理日期时间-更好的方法
marc_s

谢谢大家。抱歉,我只是SQL的新手。
佩萨尔

1
请注意,MSSQL 2012(我想也是旧版本)会将datetime转换为varchar为“ 2014-01-06T16:18:00.045”,因此,如果您也尝试匹配小时/分钟,请记住这一点。
balint 2014年

我对上述sql select的唯一问题是: WHERE CONVERT(VARCHAR(25), register_date, 25) LIKE '2009-10-10%'
Gabriel Marius Popescu

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的新手。
2009年

7

您可以使用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子句中有拼写错误,应该是“ where'2009-10-10'> = register_date”
Vishwanath Dalvi

@mr_eclair:别这么认为,其中包括10月11日之前的每个日期
Andomar

7

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

    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运营商一样。

查找所有未结日期为第一天的帐户的命令:

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

* CASTING,OpenDt因为它的价值DATETIME不仅仅在于DATE


1

对于SQL Server中的日期,LIKE运算符非常不完整。它仅适用于美国日期格式。例如,您可以尝试:

... 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 Server中直接支持like运算符。

如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-默认为时间,日期,datetime2和datetimeoffset的ODBC规范(以毫秒为单位)。-yyyy-mm-dd hh:mi:ss.mmm(24h)

这使它更容易,您可以使用:

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 Server中执行日期时间搜索而未将其转换为字符串一直存在问题。获取每个日期部分是一个过高的选择(不太可能使用索引)。当您不使用字符串转换时,一种更好的方法可能是使用范围检查。即:

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 + "%'";
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.