为什么我在同一 table 中的两个日期之间的选择不起作用?

Why my selection between two dates in the same table doesn't work?

我使用 SQL 服务器 2014,我尝试以下查询 select 在同一 table 的两个日期之间,数据类型是 nvarchar,我执行了下面的查询只显示了三行这样的('30/03/2015','30/04/2015','30/04/2015'),但实际上有('29/02/2015','30/03/2015','31/04/2015','30/04/2015','30/04/2015')

select RegisteredDate
from Student
where Student.RegisteredDate between convert(nvarchar, '30/01/2014', 103)
    and convert(nvarchar, '30/04/2015', 103)

反过来,你比较字符串的另一种方式:

select RegisteredDate from Student
where convert(date, Student.RegisteredDate, 103) between '20140130' and '20150430'

事实是那些保存为字符串的日期排序为:

'29/02/2015',
'30/03/2015',
'30/04/2015',
'30/04/2015',
'31/04/2015'

现在想象一下,您会在哪里添加过滤器值?

 '29/02/2015',

 '30/01/2014' --start date

/-------------\
|'30/03/2015',|
|'30/04/2015',|
|'30/04/2015',|
\-------------/

 '30/04/2015' --end date

 '31/04/2015'

所以 between 将 return 你那三行。 您的数据中也有 29/02/20152015 二月在 28 结束(您的表中已经有不正确的数据)。如果您选择类型 correctly.So,您将永远无法插入此类值,结论是:

为您的数据使用适当的数据类型!

尝试将字符串转换为日期,而不是将 table 中的所有日期都转换为字符串。

您正在将 table 中的所有记录转换为字符串,并且可能有数百万条记录。这样不仅你的表现会更好,而且更重要的是你会将它们与日期进行比较,而不是作为字符串。

SELECT RegisteredDate 
  FROM Student
 WHERE Student.RegisteredDate BETWEEN Convert(Date, '30/01/2014',103) AND Convert(Date, '30/04/2015', 103)

正如我在评论中所说,字符串比较使用字母顺序,从左边开始一个字符接一个字符。例如:20/01/1302 将在 01/12/4016 之后,因为“2”字符在“1”字符之后ASCII。

Update:如果Student.RegisteredDate还是nvarchar类型,则将其转换为date。如果可以的话,我建议您更改类型。如果不这样做,它可能会导致错误和性能问题。

SQL Server 2014 会自动将字符串转换为日期,但仅在需要时才进行。将 '30/04/2015' 字符串与 nvarchar 进行比较只是一个字符串比较。

因为我已经阅读了其他答案和评论,所以我建议您首先将 "RegisteredDate" 的数据类型从 "nvarchar" 更改为 "date"。其次使用这个标准'yyyy-MM-dd'下面的代码就是你需要的

select RegisteredDate 
from Student
where Student.RegisteredDate between '2014-01-30' and '2015-04-30'

您不需要任何转换,这就是我自己做的