SQL Server:SELECT * FROM [dbo]。[表] WHERE

时间:2017-12-07 17:30:46

标签: sql-server sql-server-2014

我是SQL Server新手,我试图选择两个日期之间的范围。

我的专栏是varchar(格式:dd.mm.yyyy hh:mm:ss),但如果我使用

SELECT * 
FROM [dbo].[Table] 
WHERE [Column] BETWEEN 'lower date' AND 'max date'

结果是每个日期都以前两个搜索选项开头。在我的情况下" dd" (dd.mm.yyyy hh:mm:ss)

是否有解决方案,而不将列从varchar更改为datetime

4 个答案:

答案 0 :(得分:1)

Gabriel Slomka的答案很接近,但使用的日期格式不正确。根据{{​​3}}:

,您应该使用格式104(德语)
SELECT *
FROM [dbo].[Table]
WHERE CONVERT(DATETIME, [Column], 104) BETWEEN 'lower date' AND 'max date';

答案 1 :(得分:0)

如果您的列是varchar,则可以尝试

select * from table where CONVERT(Datetime, column, 120) between lower and max

答案 2 :(得分:0)

这是一种不会改变列的方法。但是,它确实将其转换为比较。正如您所见,我从您的varchar列创建一个计算列,以与您的between子句一起使用。

declare @lowerDate datetime = '20170401'
declare @maxDate datetime = getdate()

if object_id('tempdb..#myTable') is not null drop table #myTable

create table #myTable(VarColumn varchar(64))
insert into #myTable
values
('12.02.2017 08:14:22'),
('30.05.2017 08:14:22')

;with cte as(
select 
    VarColumn
    ,NewColumn = cast(substring(convert(varchar(20),replace(VarColumn,'.','/'),113),4,2) + '/' + substring(convert(varchar(20),replace(VarColumn,'.','/'),113),1,2) + right(convert(varchar(20),replace(VarColumn,'.','/'),113),14) as datetime)
from
    #myTable)

select *
from cte
where NewColumn between @lowerDate and @maxDate

答案 3 :(得分:-1)

  

是否有解决方案,而不将列从varchar更改为datetime?

这取决于你的意思。这里的所有其他答案都是通过每次运行查询时将列数据从字符串数据更改为日期时间来实现的,并且每次执行此操作时,与正确的替代方案相比,这是大量资源浪费和不必要的缓慢。

如果你想要一个根本没有提到单词datetime的解决方案(即“不改变列”意味着不应该执行列数据的类型转换)那么你将不得不使用SUBSTR来切断你的字符串并将其重新排列为yyyymmddhhmmss或类似,然后它将适用于带有日期字符串参数的BETWEEN。但即使这样做也会操纵表数据,这自动意味着索引变得无法使用。索引的整个目的是使搜索快速查找;在这里,你不遗余力地打败这种机制并使你的查找速度变慢,同时清楚地编写代码,其唯一目的是执行查找 - 应该避免在应用程序中构建糟糕的性能,因为有一天你可能会达到状态确定它确实非常困难

如果您要做的就是避免转换列的数据类型,即使您很欣赏这就是您应该做的事情,我请求您不要这样做 - 您已声明自己是新的,并且学习。您有责任自己和软件的所有用户从一开始就学习如何正确地做到这一点。请不要成为那些采取一些质量低劣的方法并最终编写一个具有严重性能和安全漏洞的系统的另一个编写者(这种情况不一定是安全风险,但如果这显然缺乏做的愿望正确的事情有一天也会延伸到安全考虑因素,这是一个更大的问题)

最终真正的答案,因为我毫无疑问地发现我对你的实施充满热情,就是在你的表中添加另一个列,使用这些答案中的任何一个来运行一个更新语句来填充新列datetime等效于字符串数据,并删除旧列。解决问题的答案通常只投资于直接背景;我希望投资你的软件工程未来