【问题标题】:SQL left join on maximum dateSQL 在最大日期左连接
【发布时间】:2020-01-04 18:21:53
【问题描述】:

我有两张桌子:contractscontract_descriptions

contract_descriptions 上有一个名为contract_id 的列,它在contracts 表记录上是相等的。

我正在尝试加入contract_descriptions上的最新记录:

SELECT *
FROM contracts c
LEFT JOIN contract_descriptions d ON d.contract_id = c.contract_id
AND d.date_description =
  (SELECT MAX(date_description)
   FROM contract_descriptions t
   WHERE t.contract_id = c.contract_id)

它有效,但它是一种高效的方式吗?有没有办法避免第二个SELECT

【问题讨论】:

  • 你的数据库名称是什么?
  • 数据库名也是contracts
  • 我的意思是你的 RDBMS 是什么?像 MySQL 或 MSSQL 还是其他?
  • 数据库是PostgreSQL
  • 一般来说,您的查询对我来说似乎没问题。但是,如果您可以从两个表中添加具有准确预期输出的示例数据,这将有更多帮助。

标签: postgresql optimization sql-tuning


【解决方案1】:

你也可以使用DISTINCT ON:

SELECT * FROM contracts c LEFT JOIN (
    SELECT DISTINCT ON (cd.contract_id) cd.* FROM contract_descriptions cd
    ORDER BY cd.contract_id, cd.date_description DESC
) d ON d.contract_id = c.contract_id

DISTINCT ON 每个contract_id 只选择一行,而排序子句cd.date_description DESC 确保它始终是最后一个描述。

性能取决于许多值(例如,表格大小)。在任何情况下,您都应该将这两种方法与EXPLAIN 进行比较。

【讨论】:

    【解决方案2】:

    我觉得您的查询没问题。从另一个表按某种顺序仅连接 n 行的一种典型方法是横向连接:

    SELECT *
    FROM contracts c
    CROSS JOIN LATERAL
    (
      SELECT *
      FROM contract_descriptions cd
      WHERE cd.contract_id = c.contract_id
      ORDER BY cd.date_description DESC
      FETCH FIRST 1 ROW ONLY
    ) cdlast;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多