在Postresql中加入最大记录

时间:2019-01-25 16:10:47

标签: sql ruby-on-rails database postgresql ruby-on-rails-5

我有两个表:

products
+----+--------+
| id | name   |
+----+--------+
| 1  | Orange |
| 2  | Juice  |
| 3  | Fance  |
+----+--------+
reviews
+----+------------+-------+------------+
| id | created_at | price | product_id |
+----+------------+-------+------------+
| 1  | 12/12/20   | 2     | 1          |
| 2  | 12/14/20   | 4     | 1          |
| 3  | 12/15/20   | 5     | 2          |
+----+------------+-------+------------+

如何获取按最近(最高created_at)评论的价格订购的产品清单?

+------------+--------+-----------+-------+
| product_id | name   | review_id | price |
+------------+--------+-----------+-------+
| 2          | Juice  | 3         | 5     |
| 1          | Orance | 2         | 4     |
| 3          | Fance  |           |       |
+------------+--------+-----------+-------+

我使用最新的PostgreSQL。

2 个答案:

答案 0 :(得分:1)

demo:db<>fiddle

使用DISTINCT ON

SELECT
    *
FROM (
    SELECT DISTINCT ON (p.id)
        p.id,
        p.name,
        r.id as review_id,
        r.price
    FROM
        reviews r
    RIGHT JOIN products p ON r.product_id = p.id
    ORDER BY p.id, r.created_at DESC NULLS LAST
) s
ORDER BY price DESC NULLS LAST
  1. 加入两个表(products LEFT JOIN reviewreview RIGHT JOIN products)。
  2. 现在您必须下订单。首先,您要将产品分组在一起。然后,您要获取每个产品的最新条目(按降序排列,以获取最新的第一行)。
  3. DISTINCT ON始终过滤有序组的第一行。这样您就可以获得每种产品的最新条目。
  4. 要对产品行进行排序,请将1-3放入子查询中,然后按price进行排序。

答案 1 :(得分:1)

DISTINCT ON和外部联接是一种很好的方法,但是我可以这样处理:

SELECT . . .  -- whatever columns you want
FROM products p LEFT JOIN
     (SELECT DISTINCT ON (r.product_id) r.*
      FROM reviews r
      ORDER BY r.product_id, r.created_at DESC NULLS LAST
     ) r
     ON r.product_id = p.id
ORDER BY p.price DESC NULLS LAST;

DISTINCT ON之前或之后进行JOIN的差异可能很小。但是此版本的查询可以利用reviews(product_id, created_at desc)上的索引。这可能是在大量数据上取得巨大性能的胜利。

不能将ORDER BY的索引用于混合来自不同表的列。