我需要将存储在我的数据库中的日期作为varchar与今天的日期进行比较。
具体来说,我需要排除任何已经过了日期的记录。
我试过了:
SELECT * FROM tblServiceUsersSchedule
WHERE ScheduleEndDate !='' AND ScheduleEndDate < '2015/05/31'
此选定值,例如17/06 / 2012 和19/04/2015,两者都已通过,以及2015年6月1日尚未完成。
然后我尝试使用以下方式转换数据:
SELECT *
FROM tblServiceUsersSchedule
WHERE CAST(ScheduleEndDate as DATETIME) < CAST('05/31/2015' as DATETIME) AND ScheduleEndDate !='' AND ScheduleEndDate is not null
但是出现了以下错误:
导致将varchar数据类型转换为日期时间数据类型 在超出范围的价值。
我检查了后面的数据,没有一个是null,没有空白空格。所有日期都是dd / mm / yyyy格式。
我无法弄清楚如何比较存储在今天日期的varchar日期。
答案 0 :(得分:3)
将日期值存储为varchar是完全错误的。
如果可能,您应该更改表格以将它们存储为日期数据类型 您只需几个简单的步骤即可完成:
将当前列(我猜测ScheduleStartDate也是varchar)重命名为columnName_old。使用sp_rename
。
使用alter table
添加具有相应数据类型的列。
set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103)
,如下所示:script index as
如果您的sql server版本是2012或更高版本,请使用convert
。请注意,我已使用try_convert
,nullif
和ltrim
将仅包含空格的值转换为null。drop and create
- &gt; alter table
。SELECT * FROM tblServiceUsersSchedule
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
删除旧列。注意:如果在数据库的任何其他对象中引用这些列,您也必须更改这些对象。这包括存储过程,外键等。“
如果您无法更改列的数据类型,并且您的sql server版本低于2012,则需要使用如下转换:
Try_convert
请注意,如果您的列的数据不是dd / MM / yyyy格式的单行,则会引发错误。
对于sql server版本2012或更高版本,请使用SELECT * FROM tblServiceUsersSchedule
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
。如果转换失败,此函数将返回null:
CAST(GETDATE() as Date)
注意:我已使用ScheduleEndDate
删除当前日期的时间部分。这意味着您只能获得ScheduleEndDate
至少有一天的记录。如果您还要获取今天<=
所在的记录,请使用<
代替<nav class = "navbar navbar-inverse">
<div class = "navbar-header">
<button type = "button" class = "navbar-toggle" data-toggle = "collapse" data-target = "#mynav">
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
</button>
<a href = "#" class = "navbar-brand">Stack Ask</a>
</div>
<div class = "collapse navbar-collapse" id = "mynav">
<ul class = "nav navbar-nav">
<li class = "active"><a href = "#">Home</a></li>
<li><a href = "#">Education</a></li>
<li class = "dropdown"><a class = "dropdown-toggle" data-toggle = "dropdown" href = "#">Tutorials
<span class = "caret"></span>
</a>
<div class = "dropdown-menu">
<ul class = "nav navbar-nav">
<li><a href = "#">Programming Languages</a></li>
<li><a href = "#">Web Development</a></li>
</ul>
</div>
</li>
<li><a href = "#">Kingdom Centre</a></li>
<li><a href = "">About</a></li>
</ul>
<ul class = "nav navbar-nav navbar-right">
<li class = "dropdown"><a href = "#" class = "dropdown-toggle" data-toggle = "dropdown"><span class = "glyphicon glyphicon-search"></span> Search</a>
<div class = "dropdown-menu">
<ul class = "nav navbar-nav">
<li>
<form class="form-search">
<div class = "container-fluid">
<input type="text" class="form-control input-medium search-query" style = "border-radius: 25px;" />
<button type="submit" class="btn" style = "margin-top: 10px; margin-left: 5px;">Search</button>
</div>
</form>
</li>
</ul>
</div>
</li>
<li><a href = "#"><span class = "glyphicon glyphicon-user"></span> Sign Up</a></li>
<li><a href = "#"><span class = "glyphicon glyphicon-log-in"></span></span> Log In</a></li>
</ul>
</div>
</nav>
。
最后一件事:在where子句中使用列上的函数将阻止Sql Server对这些列使用任何索引。
这是您应该将列更改为适当数据类型的另一个原因。
答案 1 :(得分:0)
除了人们已经建议您永远不应将DATETIME
存储为VARCHAR
之外。始终将其存储在DATETIME
类型列中;我认为你应该在WHERE
ScheduleEndDate < '2015/05/31'
为了获得尚未过去的所有日期
ScheduleEndDate >= '2015/05/31'
您的查询应该是
SELECT * FROM tblServiceUsersSchedule
WHERE ScheduleEndDate IS NOT NULL
AND ScheduleEndDate >= '2015/05/31'
答案 2 :(得分:0)
如果您必须将日期存储为varchar(以及其他答案,这是一个差的做法),那么使用yyyy-mm-dd之类的ISO样式格式应该可以进行文本比较,而不会出现问题。 如果您的列是日期数据类型,并且您使用的是SQL 2012或更高版本,请使用DATEFROMPARTS(或其变体之一)进行日期比较,所以
WHERE DateToCompare < DATEFROMPARTS (2019, 12, 31)
而不是
WHERE DateToCompare < '2019-12-31'
SQL处理后一种很好,但是前一种更“正确”。