2012-06-08 2 views
2

Я сортирую таблицу. Скрипку можно найти here.Изменение позиции NULL при сортировке

CREATE TABLE test 
(
field date NULL 
); 

INSERT INTO test VALUES 
('2000-01-05'), 
('2004-01-05'), 
(NULL), 
('2008-01-05'); 

SELECT * FROM test ORDER BY field DESC; 

Результаты я получаю:

2008-01-05 
2004-01-05 
2000-01-05 
(null) 

Однако мне нужны результаты, чтобы быть как это:

(null) 
2008-01-05 
2004-01-05 
2000-01-05 

Таким образом, значение NULL обрабатывается, как если она выше, чем любой другой стоимость. Можно ли это сделать?

+0

Возможный дубликат [ORDER BY DATE, показывающий NULLS сначала и самые последние даты] (http://stackoverflow.com/questions/821798/order-by-date-showing-nulls-first-then-most-recent-dates) – GarethD

ответ

4

Проще всего добавить дополнительное условие сортировки первого:

ORDER BY CASE WHEN field is null then 0 else 1 END,field DESC 

Или, вы можете попробовать установить его по максимуму его типа данных:

ORDER BY COALESCE(field,'99991231') DESC 

COALESCE/ISNULL работают нормально, если вы не ч ave "real" с использованием того же максимального значения. Если вы это сделаете, и вам нужно их отличить, используйте первую форму.

+0

Да, данные имеют нормальный диапазон, и это текущие дни, годы, (не более + -10 лет) :) Спасибо за ответ :) –

+0

Первый вариант - мой естественный наклон. У меня нет доступа к БД в настоящее время, чтобы проверить мое предположение, но я ожидал бы этого; Если результирующий набор уже естественно упорядочен, последний будет планироваться с более дорогой процедурой переупорядочения, поскольку поле сортировки будет запущено с помощью 'ISNULL()', и поэтому оптимизатор не сможет «знать» о связь между естественным порядком данных и желаемым окончательным порядком. * (Это имело какой-то смысл?) * – MatBailie

4

Используйте «конец времени» маркера заменить аннулирует:

SELECT * FROM test 
ORDER BY ISNULL(field, '9999-01-01') DESC; 
+0

Ум, вы хотите, чтобы конец времени, а не начало времени, когда заказ 'desc' и нужный' null' первый –

+0

уже редактировал, но вы избили меня до него ....! –

+0

Aha! Вот так! Еще один день, когда я узнаю что-то ценное. Спасибо :) –

1

Будьте осторожны с запросами, которые вызывают функции для каждой строки, они редко масштабируются.

Это не может быть проблемой для небольших наборов данных, но будет, если они станут большими. Это должно контролироваться путем регулярного проведения тестов по запросам. Оптимизация базы данных - это только операция «Заблокировать и забыть», если ваши данные никогда не меняются (очень редко).

Иногда лучше ввести искусственный первичный столбец сортировки, например, с:

select 1 as art_id, mydate, col1, col2 from mytable where mydate is null 
union all 
select 2 as art_id, mydate, col1, col2 from mytable where mydate is not null 
order by art_id, mydate desc 

Затем используйте только result_set["everything except art_id"] в ваших программах.

Поступая таким образом, вы не вводите (возможно) медленные функции на строку, вместо этого вы полагаетесь на быстрый поиск индекса на столбце mydate. И продвинутые механизмы выполнения могут фактически запускать эти два запроса одновременно, объединяя их, как только они завершатся.

+0

Спасибо за совет :) –

Смежные вопросы