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

时间:2017-01-11 00:24:24

标签: postgresql postgresql-9.3

SQL小提琴:http://sqlfiddle.com/#!15/1da00/5

我有一张看起来像这样的表:

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的行减少到30天,然后按created_date排序。我还希望按order_index

updated_date = 1的行进行排序

1 个答案:

答案 0 :(得分: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;

当排序列具有不同类型时,此方法非常有用。