简体   繁体   中英

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.

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. You can use below link to see if its behaving correctly. link -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.

Firstly we need to convert the value to as ISO value. I'm also, however, going to create a new column called Bad_Sent_Date , to store values that could not be converted. 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' .

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 :

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:

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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