2017-01-11 1 views
0

SQL Скрипки: http://sqlfiddle.com/#!15/1da00/5Сортировать по CREATED_DATE, если менее 1 месяца, иначе сортировать по updated_date

У меня есть таблица, которая выглядит примерно так:

products 
+-----------+-------+--------------+--------------+ 
| name | price | created_date | updated_date | 
+-----------+-------+--------------+--------------+ 
| chair  | 50 | 10/12/2016 | 1/4/2017  | 
| desk  | 100 | 11/4/2016 | 12/27/2016 | 
| TV  | 500 | 12/1/2016 | 1/2/2017  | 
| computer | 1000 | 12/28/2016 | 1/1/2017  | 
| microwave | 100 | 1/3/2017  | 1/4/2017  | 
| toaster | 20 | 1/9/2017  | 1/9/2017  | 
+-----------+-------+--------------+--------------+ 

Я хочу заказать эту таблицу в путь, когда продукт был создан менее чем за 30 дней, эти результаты должны отображаться первыми (и заказываться по обновленной дате). Если продукт был создан 30 или более дней назад я хочу, чтобы показать после того, как (и он заказал по обновленной дате в этой группе)

Это то, что результат должен выглядеть следующим образом:

products - desired results 
+-----------+-------+--------------+--------------+ 
| name | price | created_date | updated_date | 
+-----------+-------+--------------+--------------+ 
| toaster | 20 | 1/9/2017  | 1/9/2017  | 
| microwave | 100 | 1/3/2017  | 1/4/2017  | 
| computer | 1000 | 12/28/2016 | 1/1/2017  | 
| chair  | 50 | 10/12/2016 | 1/4/2017  | 
| TV  | 500 | 12/1/2016 | 1/2/2017  | 
| desk  | 100 | 11/4/2016 | 12/27/2016 | 
+-----------+-------+--------------+--------------+ 

Я ве начал писать этот запрос:

SELECT *, 
    CASE 
     WHEN created_date > NOW() - INTERVAL '30 days' THEN 0 
     ELSE 1 
    END AS order_index 
FROM products 
ORDER BY order_index, created_date DESC 

но только привести строки с created_date менее thatn 30 дней в верхней части, а затем заказанный created_date. Я хочу также отсортировать строки, где order_index = 1 по updated_date

ответ

1

К сожалению, в версии 9.3 только позиционные номера столбцов или выражения, включающие столбцы таблицы могут быть использованы в order by так order_index не доступен case вообще и его позиция не хорошо определены, потому что он приходит после * в списке столбцов.

Это будет работать.

order by 
    created_date <= (current_date - 30) , case 
    when created_date > (current_date - 30) then created_date 
    else updated_date end desc 

В качестве альтернативы общее выражение таблицы может использоваться для обертывания результата и затем может быть заказано любым столбцом.

WITH q AS(
    SELECT *, 
     CASE 
      WHEN created_date > NOW() - INTERVAL '30 days' THEN 0 
      ELSE 1 
     END AS order_index 
    FROM products 
) 
SELECT * FROM q 
ORDER BY 
    order_index , 
    CASE order_index 
     WHEN 0 THEN created_date 
     WHEN 1 THEN updated_date 
    END DESC; 

Третий подход заключается в использовании нулей.

order by 
    case 
    when created_date > (current_date - 30) then created_date 
    end desc nulls last, 
    updated_date desc; 

Этот подход может быть полезен, когда колонны заказов имеют разные типы.

+0

Это не дает правильных результатов. Кроме того, вы можете использовать 'order_index'. Я планирую добавить больше значений в 'order_index', поэтому его не следует вынимать. – Xecure

+0

oops. order_index. сложнее использовать, вычисляемые столбцы могут ссылаться только по положению, поэтому они не могут использоваться в выражениях. – Jasen