【问题标题】:postgres join max datepostgres 加入最大日期
【发布时间】:2016-08-10 14:59:56
【问题描述】:

我需要构建一个连接,它可以为我提供每种产品的最新价格。为了示例的目的,我大大简化了表结构,每个表的行数将达到数百万。我之前在这方面的尝试并不是很有效。

【问题讨论】:

  • 这个问题是因为您在编写查询以获得正确结果时遇到问题吗?或者您在以高效的方式编写查询时遇到问题?
  • @MarkHildreth 只要数据集很小,我就可以整天编写“正常运行”的查询。一旦我尝试在我的大型数据库上运行这些相同的子查询连接,它就永远不会返回结果。所以是的,问题肯定是效率。
  • @bopritchard 在这种情况下,您应该提供更多信息。至少,您应该给出一个您尝试运行的查询,以及结果的 EXPLAIN。您尝试运行的表的架构和索引列表也将很有用。我还建议对表运行分析/真空,然后再次尝试查询。

标签: sql postgresql inner-join aggregate


【解决方案1】:

虽然 DISTINCT ON 答案适用于我的实例,但我发现有一种更快的方法可以让我获得所需的内容。

SELECT DISTINCT ON(u.id) u.id, (CAST(data AS JSON) ->> 'Finished') AS Finished, ee.post_value
    FROM users_user u
    JOIN events_event ee on u.id = ee.actor_id
    WHERE u.id > 20000
    ORDER BY u.id DESC, ee.time DESC
;

在我的数据库上大约需要 25 秒,而

SELECT u.id, (CAST(data AS JSON) ->> 'Finished') AS Finished, e.post_value
    FROM users_user u
    JOIN events_event e on u.id = e.actor_id
    LEFT JOIN events_event ee on ee.actor_id = e.actor_id AND ee.time > e.time
    WHERE u.id > 20000 AND ee.id IS NULL
    ORDER BY u.id DESC
;

大约需要 15 秒。

【讨论】:

    【解决方案2】:

    在 PostgreSQL 中,您可以尝试 DISTINCT ON 仅获取每个产品 ID 的第一行,以降序 create_date 顺序;

    SELECT DISTINCT ON (products.id) products.*, prices.* 
    FROM products 
    JOIN prices 
      ON products.id = prices.product_id 
    ORDER BY products.id, create_date DESC
    

    (当然,除了说明目的,您当然应该选择您需要的确切列)

    【讨论】:

    • 这是完美的,正是 DISTINCT ON 的用途;谢谢。
    【解决方案3】:

    最简单的方法是使用row_number 函数。

    select p.name,t.amount as latest_price
    from (select p.*, row_number() over(partition by product_id order by create_date desc) as rn 
          from prices p) t 
    join products p on p.id = t.product_id
    where rn = 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-21
      相关资源
      最近更新 更多