简体   繁体   English

当列在 Microsoft SQL Server 中为 nvarchar 类型时如何按日期排序

[英]How to order by date when a column is of type nvarchar in Microsoft SQL Server

I have an issue where I created a column sent_Date of type nvarchar while it's storing date and time.我有一个问题,我在存储日期和时间时创建了一个nvarchar类型的sent_Date列。

Now when I try to sort it by date, it's not doing so correctly.现在,当我尝试按日期对其进行排序时,它的操作不正确。

I am using this query:我正在使用这个查询:

select *
from tbl_skip 
where sent_date > '9/27/2020 7:29:11 PM'
order by SENT_DATE desc

You can convert the data from string to datetime.您可以将数据从字符串转换为日期时间。
Please note i used 100 as an example to convert to date time.请注意,我以 100 为例转换为日期时间。 You can use below link to see if its behaving correctly.您可以使用以下链接查看其行为是否正确。 link -https://www.w3schools.com/sql/func_sqlserver_convert.asp链接-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

Like the comments have said, the real solution here is fix your design.正如评论所说,这里真正的解决方案是修复您的设计。 That means changing the column's data type an nvarchar to a date and time data type, I'm going to use a datetime2(0) here, as your data is accurate to a second, so seems the most appropriate.这意味着将列的数据类型从nvarchar更改为日期和时间数据类型,我将在这里使用datetime2(0) ,因为您的数据精确到一秒,因此看起来最合适。

Firstly we need to convert the value to as ISO value.首先,我们需要将值转换为 ISO 值。 I'm also, however, going to create a new column called Bad_Sent_Date , to store values that could not be converted.但是,我还将创建一个名为Bad_Sent_Date的新列,以存储无法转换的值。 Experience has taught many of us that systems that incorrectly use string data types to store dates (or numerical data) rarely have good data integrity rules on the value (because if they did, it wouldn't be an nvarchar ) to start, so have bad values like ' 29/02/2019' or mix styles, such as having both '09/29/2020' and '29/09/2020' .经验告诉我们许多人错误地使用字符串数据类型来存储日期(或数字数据)的系统很少有关于值的良好数据完整性规则(因为如果他们这样做,它就不会是nvarchar )开始,所以有错误的值,例如'29/09/2020' 29/02/2019'或混合样式,例如同时具有'09/29/2020''29/09/2020'

Based on the single example we have, I will assume your data is supposed to be in the format MM/dd/yy hh:mm:ss AM/PM :基于我们拥有的单个示例,我将假设您的数据应该采用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

Now we have an ISO format, we can change the table's data type:现在我们有了 ISO 格式,我们可以更改表的数据类型:

ALTER TABLE dbo.tbl_skip ALTER COLUMN Sent_date datetime2(0) NULL;

Note that if you do have constraints on the column Sent_date , or it isn't NULL able, you will first need to DROP said CONSTRAINT s, change the column to be NULL able and then recreate said CONSTRAINT s after you have altered the column.请注意,如果您确实Sent_date列有约束,或者它不能为NULL ,则您首先需要DROP所述CONSTRAINT ,将列更改为NULL ,然后在更改列后重新创建所述CONSTRAINT

You can also review the "dates" that failed to be converted with the following:您还可以使用以下命令查看未能转换的“日期”:

SELECT bad_sent_date
FROM dbo.tbl_skip
WHERE bad_sent_date IS NOT NULL
  AND Sent_date IS NULL;

Once that's all done, then your query simply needs an update to use an unambiguous date literal, and it'll work:一旦这一切都完成了,那么您的查询只需要更新以使用明确的日期文字,它就会起作用:

SELECT *
FROM tbl_skip
WHERE sent_date > '2020-09-27T19:29:11' --'9/27/2020 7:29:11 PM'
ORDER BY SENT_DATE DESC;

You should be able to convert it to a datetime您应该能够将其转换为日期时间

select *
from tbl_skip 
where sent_date > '9/27/2020 7:29:11 PM'
order by convert(datetime,SENT_DATE) desc

Just make sure the data in column is legit.只要确保列中的数据是合法的。 If so, it would make sense to convert the column type to a datetime.如果是这样,将列类型转换为日期时间是有意义的。

alter table tbl_skip alter column SENT_DATE datetime

If the data is mixed, you may need to fix it or use something like如果数据混合,您可能需要修复它或使用类似

order by try_convert(datetime,SENT_DATE) desc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM