6

我使用 SQL Server 2014,我尝试使用以下查询在同一个表中的两个日期之间进行选择,数据类型是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)
4

3 回答 3

3

反过来投射,以其他方式比较字符串:

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会返回你那三行。你也有你的数据29/02/20152015二月结束(您的表格中28已有不正确的数据)。如果您正确选择类型,您将永远无法插入此类值。因此结论是:

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

于 2015-04-30T15:35:16.943 回答
2

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

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

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

于 2015-05-06T14:25:20.530 回答
1

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

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

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”字符在 ASCII 中“1”字符之后。

更新:如果 Student.RegisteredDate 仍然是 nvarchar 类型,则将其转换为日期。如果可以的话,我建议您更改类型。如果您不这样做,它可能是错误和性能问题的根源。

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

于 2015-04-30T15:47:35.753 回答