如果小于 1 个月,则按 created_date 排序,否则按 updated_date 排序

Order by created_date if less than 1 month old, else sort by updated_date

SQL Fiddle: http://sqlfiddle.com/#!15/1da00/5

我有一个看起来像这样的 table:

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     |
+-----------+-------+--------------+--------------+

我想订购此 table 如果产品创建时间少于 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 少于 30 天的行带到顶部,然后按 created_date 排序。我还想按 updated_date

order_index = 1 的行进行排序

不幸的是,在 9.3 版中,只有涉及 table 列的位置列号或表达式可以在 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

或者,可以使用常见的 table 表达式来包装结果,然后可以按任何列对其进行排序。

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;

当排序列的类型不同时,此方法很有用。