我一直在努力想出这个问题,但我开始放弃了。
为简化案例,假设我有两张桌子。主表格为articles
,我将其与contracts
一起加入。合同表有结束日期。 我只想从每篇文章中选择一(1)行,选择最新的 contract_to
日期。
我尝试过类似LEFT JOIN contracts ON (contracts.article = articles.id) ORDER BY contract_to DESC LIMIT 1
的尝试,但显然它不起作用。
我该怎么做?
请假设下面合同表中每行的日期范围不同 所有文章合同的最新日期也不尽相同,所以我不能确定最新日期是什么,然后将其粘贴到WHERE子句中。
答案 0 :(得分:3)
要获取最新的contract_to
值,您需要MAX()
聚合。执行此操作的正确方法是使用子查询连接仅获取article
和MAX(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的奇怪行为。
答案 1 :(得分: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
;
答案 2 :(得分: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)
上的索引,这甚至应该相对有效。