PostgreSQL按SubQuery排序

时间:2014-12-05 17:12:25

标签: sql postgresql sql-order-by

我有这个数据库结构:

表:

分类

id    | category    
1     | fruit      
2     | cars       
3     | tables        

产品

id    | product     | category_id
1     | banana      | 1
2     | apple       | 1
3     | orange      | 1
4     | example 1   | 2
5     | example 2   | 3

USER_LIST

id    | product_id  | user_id | bought_date
1     | 1           | 1       | 2012-06-21 11:00:00
2     | 2           | 1       | 2012-06-21 06:00:00
3     | 4           | 1       | 2012-06-21 08:00:00
4     | 5           | 1       | 2012-06-21 01:00:00

我想要的是创建一个“按类别按buy_date(desc)排序”的查询。 在这种情况下,预期结果是:

banana
apple
example 1
example 2

我的查询:

SELECT c.id, u.bought_date
    FROM categry as c
    left join product p on (c.id=p.category_id)
    left join user_list u on (p.id=u.product_id)
    WHERE u.user_id=3 
    ORDER BY u.bought_date DESC NULLS LAST

但这只是按购买日期进行的简单排序......

有了这个结果:

banana
example 1
apple
example 2

3 个答案:

答案 0 :(得分:0)

听起来好像你只需要order by子句中的两列:

SELECT c.id, u.bought_date
FROM categry as c
left join product p on (c.id=p.category_id)
left join user_list u on (p.id=u.product_id)
WHERE u.user_id=3 
ORDER BY category_id, u.bought_date DESC NULLS LAST

答案 1 :(得分:0)

我想到了一个订单。您想按每个类别的最早或最晚日期订购。为此,请使用窗口函数。

SELECT c.id, u.bought_date, max(u.bought_date) over (partition by c.id) as category_bd
FROM categry c left join
     product p
     on (c.id=p.category_id) left join
     user_list u
     on (p.id=u.product_id)
WHERE u.user_id = 3 
ORDER BY category_bd DESC NULLS LAST, u.bought_date DESC NULLS LAST

答案 2 :(得分:0)

假设缺少信息:

  1. bought_date定义为NOT NULL
  2. 每个产品user_list中可以有多行,并且它们可以有不同的bought_date
  3. 首先按其类别的最新bought_date订购产品,
    以及他们最新的bought_date next。
  4. SELECT p.product
    FROM   product   p
    JOIN   user_list u ON u.product_id = p.id
    GROUP  BY 1
    ORDER  BY max(max(u.bought_date)) OVER (PARTITION BY p.category_id) DESC
            , max(u.bought_date) DESC;
    
    • 您根本不需要查询中的表categry
    • 每个类别获取最新bought_date的窗口函数可以进入ORDER BY子句。
    • 是的,这是一个关于聚合max(u.bought_date)的窗口函数。
    • 显然你不会在结果中想要橘子,因为没有人带来"它们。
      使用JOIN,而不是 LEFT JOIN