【问题标题】:Join max records in Postresql在 Postgresql 中加入最大记录
【发布时间】:2019-01-25 16:10:47
【问题描述】:

我有两张桌子:

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

我如何获得按最近(max created_at)评论价格订购的产品列表?

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

我使用最新的 PostgreSQL。

【问题讨论】:

  • 您的问题到底是什么?请出示您的查询。你被困在哪里了?
  • 我不明白:你是按产品订购,价格订购日期(这是什么日期格式?mm/dd/yy?)
  • @S-Man:数据库中的日期没有格式(除非它被不恰当地存储为字符串或整数)。
  • 啊,好吧。是的,显然是美国的:mm/dd/yy。结果的顺序是按价格降序排列(“按价格排序的产品列表”)。
  • 好的。您想要products 的所有行。你当然知道该怎么做。您还应该了解外部连接。您想要每个产品的最新评论。那是具有最大日期或不存在较新评论的那个。您可以使用子查询DISTINCT ONROW_NUMBER()。你应该能够想出something

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


【解决方案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 排序。

【讨论】:

  • dbfiddle.uk/… 它不起作用,因为它先按 id 对产品进行排序,然后再按价格排序。我的 id 为 2(价格为 5)的小提琴产品应该在第一位。
  • 是的,我也看到了。修好了
【解决方案2】:

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;

JOIN 之前或之后执行DISTINCT ON 的区别可能看起来很小。但是这个版本的查询可以利用reviews(product_id, created_at desc) 上的索引。这可能会在大量数据上取得巨大的性能胜利。

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

【讨论】:

    猜你喜欢
    • 2012-01-06
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    相关资源
    最近更新 更多