[英]How to order by date when a column is of type nvarchar in Microsoft SQL Server
我有一个问题,我在存储日期和时间时创建了一个nvarchar
类型的sent_Date
列。
现在,当我尝试按日期对其进行排序时,它的操作不正确。
我正在使用这个查询:
select *
from tbl_skip
where sent_date > '9/27/2020 7:29:11 PM'
order by SENT_DATE desc
您可以将数据从字符串转换为日期时间。
请注意,我以 100 为例转换为日期时间。 您可以使用以下链接查看其行为是否正确。 链接-https://www.w3schools.com/sql/func_sqlserver_convert.asp
select *
from tbl_skip
where sent_date > convert(datetime,'9/27/2020 7:29:11 PM',100)
ORDER BY CONVERT(datetime,SENT_DATE,100) desc
正如评论所说,这里真正的解决方案是修复您的设计。 这意味着将列的数据类型从nvarchar
更改为日期和时间数据类型,我将在这里使用datetime2(0)
,因为您的数据精确到一秒,因此看起来最合适。
首先,我们需要将值转换为 ISO 值。 但是,我还将创建一个名为Bad_Sent_Date
的新列,以存储无法转换的值。 经验告诉我们许多人错误地使用字符串数据类型来存储日期(或数字数据)的系统很少有关于值的良好数据完整性规则(因为如果他们这样做,它就不会是nvarchar
)开始,所以有错误的值,例如'29/09/2020'
29/02/2019'
或混合样式,例如同时具有'09/29/2020'
和'29/09/2020'
。
基于我们拥有的单个示例,我将假设您的数据应该采用MM/dd/yy hh:mm:ss AM/PM
格式:
ALTER TABLE dbo.tbl_skip ADD Bad_Sent_Date nvarchar(30) NULL;
GO
UPDATE TABLE dbo.tbl_skip
SET Bad_Sent_Date = CASE WHEN TRY_CONVERT(datetime2(0),Sent_date,101) IS NULL THEN Sent_date END,
Sent_Date = CONVERT(nvarchar(30),TRY_CONVERT(datetime2(0),Sent_date,101),126);
GO
现在我们有了 ISO 格式,我们可以更改表的数据类型:
ALTER TABLE dbo.tbl_skip ALTER COLUMN Sent_date datetime2(0) NULL;
请注意,如果您确实对Sent_date
列有约束,或者它不能为NULL
,则您首先需要DROP
所述CONSTRAINT
,将列更改为NULL
,然后在更改列后重新创建所述CONSTRAINT
。
您还可以使用以下命令查看未能转换的“日期”:
SELECT bad_sent_date
FROM dbo.tbl_skip
WHERE bad_sent_date IS NOT NULL
AND Sent_date IS NULL;
一旦这一切都完成了,那么您的查询只需要更新以使用明确的日期文字,它就会起作用:
SELECT *
FROM tbl_skip
WHERE sent_date > '2020-09-27T19:29:11' --'9/27/2020 7:29:11 PM'
ORDER BY SENT_DATE DESC;
您应该能够将其转换为日期时间
select *
from tbl_skip
where sent_date > '9/27/2020 7:29:11 PM'
order by convert(datetime,SENT_DATE) desc
只要确保列中的数据是合法的。 如果是这样,将列类型转换为日期时间是有意义的。
alter table tbl_skip alter column SENT_DATE datetime
如果数据混合,您可能需要修复它或使用类似
order by try_convert(datetime,SENT_DATE) desc
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.