Пытаюсь заказать по дате. Я хочу, чтобы самые свежие свидания были первыми. Это достаточно просто, но есть много записей с нулевым значением, которые предшествуют любым записям с датой.
Я безуспешно пробовал несколько вещей:
ORDER BY ISNULL(Next_Contact_Date, 0)
ORDER BY ISNULL(Next_Contact_Date, 999999999)
ORDER BY coalesce(Next_Contact_Date, 99/99/9999)
Как сделать заказ по дате, чтобы нули приходили последними? Тип данных - smalldatetime
.
sql-server
sql-server-2005
tsql
UpHelix
источник
источник
Ответы:
smalldatetime
имеет диапазон до 6 июня 2079 г., поэтому вы можете использоватьЕсли в законных записях не будет этой даты.
Если это не предположение, вы можете полагаться на более надежный вариант - сортировку по двум столбцам.
ORDER BY CASE WHEN Next_Contact_Date IS NULL THEN 1 ELSE 0 END, Next_Contact_Date
Оба приведенных выше предложения не могут использовать индекс, чтобы избежать сортировки и дать похожие планы.
Еще одна возможность, если такой индекс существует:
SELECT 1 AS Grp, Next_Contact_Date FROM T WHERE Next_Contact_Date IS NOT NULL UNION ALL SELECT 2 AS Grp, Next_Contact_Date FROM T WHERE Next_Contact_Date IS NULL ORDER BY Grp, Next_Contact_Date
источник
VARCHAR
полям (напримерORDER BY ISNULL(my_varchar, 'ZZZZZZ')
), и он чрезвычайно полезен, особенно для получения заказов определенным образом при использованииGROUP BY . . . GROUPING SETS
. Спасибо, что разместили это.По словам Ицика Бен-Гана, автора книги « Основы T-SQL для MS SQL Server 2012» : «По умолчанию SQL Server сортирует метки NULL перед значениями, отличными от NULL . Чтобы получить метки NULL для сортировки в последнюю очередь, вы можете использовать выражение CASE, которое возвращает 1 , когда « Next_Contact_Date столбец NULL ,» и 0 , если он не NULL Непро-. NULL метки получить 0 обратно из выражения, поэтому они сортируют перед тем NULL знаков (которые получают 1) Это. СЛУЧАЙ выражение используется в качестве первой столбец сортировки. " Next_Contact_Datecolumn "следует указать как второй столбец сортировки. Таким образом, ненулевые отметки правильно сортируют между собой." Вот запрос решения для вашего примера для MS SQL Server 2012 (и SQL Server 2014):
ORDER BY CASE WHEN Next_Contact_Date IS NULL THEN 1 ELSE 0 END, Next_Contact_Date;
Эквивалентный код с использованием синтаксиса IIF:
источник
Если ваш SQL не поддерживает
NULLS FIRST
илиNULLS LAST
, самый простой способ сделать это - использоватьvalue IS NULL
выражение:поставить нули в конец (
NULLS LAST
) илипоставить нули впереди. Это не требует знания типа столбца, и его легче читать, чем
CASE
выражение.РЕДАКТИРОВАТЬ: Увы, хотя это работает в других реализациях SQL, таких как PostgreSQL и MySQL, это не работает в MS SQL Server. У меня не было SQL Server для тестирования, и я полагался на документацию Microsoft и тестирование с другими реализациями SQL. Согласно Microsoft,
value IS NULL
это выражение, которое должно использоваться, как и любое другое выражение. ИORDER BY
должен принимать выражения как и любой другой оператор, который принимает выражение. Но на самом деле это не работает.Поэтому лучшим решением для SQL Server является
CASE
выражение.источник
источник
Next_Contact_Date
равна нулюExplicit conversion from data type date to bigint is not allowed.
Немного поздно, но, возможно, кому-то это пригодится.
Для меня ISNULL был исключен из-за сканирования таблицы. UNION ALL потребует, чтобы я повторил сложный запрос, и из-за того, что я выбрал только TOP X, это было бы не очень эффективно.
Если у вас есть возможность изменить дизайн стола, вы можете:
Добавьте еще одно поле для сортировки, например Next_Contact_Date_Sort.
Создайте триггер, который заполняет это поле большим (или маленьким) значением, в зависимости от того, что вам нужно:
CREATE TRIGGER FILL_SORTABLE_DATE ON YOUR_TABLE AFTER INSERT,UPDATE AS BEGIN SET NOCOUNT ON; IF (update(Next_Contact_Date)) BEGIN UPDATE YOUR_TABLE SET Next_Contact_Date_Sort=IIF(YOUR_TABLE.Next_Contact_Date IS NULL, 99/99/9999, YOUR_TABLE.Next_Contact_Date_Sort) FROM inserted i WHERE YOUR_TABLE.key1=i.key1 AND YOUR_TABLE.key2=i.key2 END END
источник
Используйте desc и при необходимости умножьте на -1. Пример сортировки int по возрастанию с последними нулями:
select * from (select null v union all select 1 v union all select 2 v) t order by -t.v desc
источник
Я знаю, что это старый, но это то, что у меня сработало
источник