1

我一直在努力解决这个问题,但我开始放弃了。

为了简化案例,假设我有 2 个表。主表是articles,我将加入它contracts。合同表有一个结束日期。我只想从每篇文章中选择 1(一)行,选择最新 contract_to 日期。

我试过类似LEFT JOIN contracts ON (contracts.article = articles.id) ORDER BY contract_to DESC LIMIT 1的东西,但显然它不起作用。

我该怎么做呢?

请假装下表中每一行的日期范围不同。
此外,所有文章合同的最晚日期也不相同,所以我不能只确定最晚日期是什么,然后将其粘贴到 WHERE 条款中。

在此处输入图像描述

4

3 回答 3

3

要获得最新contract_to值,您需要一个MAX()聚合。执行此操作的正确方法是使用子查询连接来仅获取articleMAX(contract_to)值,然后将其与行的剩余值连接。最后,整个结构可以靠在articles桌子上。

SELECT
  articles.*,
  contracts.*
FROM 
  articles
  /* Join against a subquery which returns only the article and latest contract_to */
  LEFT JOIN (
    SELECT article, MAX(contract_to) AS contract_to
    FROM contracts
    GROUP BY article
  ) maxcontract ON articles.article_id = maxcontract.article
  /* and join that against the rest of the contracts table, on those two column values */
  JOIN contracts 
    ON maxcontract.article = contracts.article
    AND maxcontract.contract_to = contracts.contract_to

由于 MySQL 对GROUP BY子句的内容很宽松,这种方法实际上可能不是必需的,单独对contracts表进行连接,您可能可以单独使用子查询连接来执行此操作,但这在大多数其他 RDBMS 中不起作用,这是真正正确的方法是不依赖 MySQL 的怪异行为。

于 2013-08-17T21:25:00.070 回答
1

MySQL 没有一些 DBMS 提供的很好的分析功能,但你可以写(例如):

SELECT ...
  FROM articles
  LEFT
 OUTER
  JOIN ( SELECT article,
                MAX(contract_to) AS contract_to
           FROM contracts
          GROUP
             BY article
       ) articles_to_max_contracts
    ON articles_to_max_contracts.article = articles.id
  LEFT
 OUTER
  JOIN contracts
    ON contracts.article = articles.id
   AND contracts.contract_to = articles_to_max_contracts.contract_to
;
于 2013-08-17T21:25:16.287 回答
0

要仅获取价格,您还可以使用相关子查询来执行此操作:

select a.*,
       (select price
        from contracts c
        where a.article = c.article
        order by contract_from desc
        limit 1
       ) as lastPrice
from articles a;

有了索引,contracts(article, contract_from)这甚至应该是相对有效的。

于 2013-08-17T22:39:48.843 回答