Как упорядочить по дате, если столбец имеет тип nvarchar в Microsoft SQL Server

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня возникла проблема, когда я создал столбец sent_Date типа nvarchar , в котором хранятся дата и время.

Теперь, когда я пытаюсь отсортировать его по дате, это делается неправильно.

Я использую этот запрос:

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

Комментарии:

1. Исправьте свои данные, чтобы вы использовали правильный тип для хранения даты / времени. Это самое простое решение.

2. Почему вы храните данные о дате и времени в a nvarchar в первую очередь? Существует несколько типов даты и времени , которые являются гораздо более подходящими.

3. Помимо упорядочения, как вы думаете, что является результатом '11/27/2020 7:29:11 PM' > '9/27/2020 7:29:11 PM' ?

4. Я использовал приведенное ниже, и у меня все получилось. выберите * из tbl_skip, где CONVERT(datetime,SENT_DATE) > ‘2020-09-28 19:29:11.000’ порядок по ПРЕОБРАЗОВАНИЮ (datetime,SENT_DATE) desc

Ответ №1:

Как уже говорилось в комментариях, реальное решение здесь — исправить ваш дизайн. Это означает изменение типа данных столбца nvarchar an на тип данных даты и времени, я собираюсь использовать datetime2(0) здесь, поскольку ваши данные с точностью до секунды, поэтому они кажутся наиболее подходящими.

Во-первых, нам нужно преобразовать значение в значение ISO. Однако я также собираюсь создать новый столбец с именем Bad_Sent_Date для хранения значений, которые не удалось преобразовать. nvarchar Опыт 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;
  

Комментарии:

1. Я использовал приведенное ниже, и оно отлично работало выберите * из tbl_skip, где CONVERT(datetime,SENT_DATE) > ‘2020-09-28 19:29:11.000’ порядок ПРЕОБРАЗОВАНИЯ (datetime,SENT_DATE) desc

2. Но это не исправляет проблему, @ahmed .

Ответ №2:

Вы можете преобразовать данные из string в datetime.
Пожалуйста, обратите внимание, что я использовал 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
  

Комментарии:

1. Спасибо, я использовал приведенный ниже select * из tbl_skip, где CONVERT(datetime,SENT_DATE) > ‘2020-09-28 19:29:11.000’ порядок по ПРЕОБРАЗОВАНИЮ (datetime,SENT_DATE) desc

2. Всегда полезно указать формат, но, эй, если это сработает, я счастлив 🙂

Ответ №3:

Вы должны иметь возможность преобразовать его в datetime

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

Просто убедитесь, что данные в столбце являются законными. Если это так, имеет смысл преобразовать тип столбца в datetime .

 alter table tbl_skip alter column SENT_DATE datetime
  

Если данные смешаны, вам может потребоваться исправить это или использовать что-то вроде

 order by try_convert(datetime,SENT_DATE) desc
  

Комментарии:

1. Остерегайтесь всех этих convert by Jeremy или Koushik, потому что они не будут работать в рабочей среде, ТОЛЬКО если сеанс подключенного пользователя является английским. Для всех остальных пользователей anykind дата, сформированная в виде строки, не использует тот же шаблон. Так что советы Гордона и Ларну — самые правильные ответы…

2. Я использовал этот select * из tbl_skip, где CONVERT(datetime,SENT_DATE) > ‘2020-09-28 19:29:11.000’ порядок по ПРЕОБРАЗОВАНИЮ (datetime,SENT_DATE) desc