MySQL选择特定值的最新行

时间:2017-12-22 08:34:16

标签: mysql

我正在努力围绕制作一个能够注意到正确结果的MySQL查询。

我有一张结构如下的表:

workflow_status_history:

id    reference         status
 1    308ffn3oneb    Lead Received
 2    308ffn3oneb    Quoted
 3    308ffn3oneb    Invoiced
 4    853442ec2fc    Lead Received

如您所见,workflow_status_history表保存了系统中每个工作流的所有状态的历史记录,而不是用新状态替换或覆盖以前的状态。这有助于深入报告和审计。工作流的起始状态始终为Lead Received

但问题是,我需要选择表格中每行的reference字段,其中最新状态为{ {1}}。因此,在上面的示例中,字段编号Lead Received将返回,但字段412将不会返回,因为该工作流参考的最新状态为{{1 }}。但是,如果3(字段编号Invoiced)获得853442ec2fc以外的新状态,则下次查询运行时也不会返回。

我当前的查询如下:

4

当然,这并不会返回所需的结果,因为Lead Received子句确保它返回具有SELECT *, MAX(id) FROM workflow_status_history WHERE 'status' = 'Lead Received' GROUP BY reference LIMIT 20状态的所有行,而不管它是最新状态还是不。因此,它将始终返回表格中的前20个分组工作流程参考。

如何生成正确的查询以返回所需的结果?

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

这是左连接本身的情况。此查询中的想法是: 选择所有状态为' Lead Received'没有具有相同引用和更高ID的行。我假设你只使用id来确定什么是新的'状态,没有时间戳等。

SELECT
  DISTINCT h1.reference
FROM
  workflow_status_history h1 LEFT JOIN workflow_status_history h2 ON 
                  h1.reference = h2.reference AND 
                  h1.id < h2.id

WHERE
  h1.status = 'Lead Received' AND
  h2.id IS NULL

答案 1 :(得分:1)

虽然@Martin Schneider答案是正确的,但以下是另外两种实现预期输出的方法

在同一张桌子上使用内部联接

select a.*
from workflow_status_history a
join (
  select reference,max(id) id
  from workflow_status_history
  group by reference
) b using(reference,id)
where a.status = 'Lead Received';

使用相关子查询

select a.*
from workflow_status_history a
where a.status = 'Lead Received'
and a.id = (select max(id)
            from workflow_status_history
            where reference = a.reference)

DEMO