Mysql获取状态的最新行

时间:2014-01-13 14:08:17

标签: mysql sql greatest-n-per-group

我有一个包含多种状态的日志表。它记录外部系统中物理对象的位置。我想获取每个不同物理对象的状态的最新行。

我需要每个状态的typeid列表及其数量,减去具有另一个状态的条目的typeid数量,该状态晚于具有我们正在查找的状态的行。

例如,每个状态移动都被记录下来但没有别的。

这是问题所在,我没有为每个物理对象提供不同的ID。我只能根据日志表的状态计算出有多少。

我试过

    SELECT dl.id, dl.status
    FROM  `log` AS dl
    INNER JOIN (
      SELECT MAX(  `date` ) , id
      FROM  `log` 
      GROUP BY id ORDER BY `date` DESC 
    ) AS dl2
    WHERE dl.id = dl2.id

但这需要一个不同的类型ID才能工作。

我的表有主键ID,日期时间,状态,产品类型_id。有四种不同的状态。

产品必须通过所有状态。

示例数据。

date       typeid status    id

2014-01-13 PF0180 shopfloor 71941
2014-01-13 ND0355 shopfloor 71940
2014-01-10 ND0355 machine   71938
2014-01-10 ND0355 machine   71937
2014-01-10 ND0282 machine   7193

当选择状态车间的结果时我想要

quantity typeid
1        ND0355
1        PF0180

选择状态机时我想要

quantity typeid
1        ND0282
1        ND0355

状态的顺序无关紧要,只有产品的后续条目才有意义。

3 个答案:

答案 0 :(得分:0)

您需要按status获取最长的日期,而不是id。然后加入状态日期相同的日志表。

SELECT dl.id, dl.status
FROM  `log` AS dl
INNER JOIN (
  SELECT status, MAX(  `date` ) AS date
  FROM  `log` 
  GROUP BY status ORDER BY NULL
) AS dl2 USING (status, date);

在此表上有一个(status, date)索引会很有帮助,这将允许子查询作为仅索引查询运行。

答案 1 :(得分:0)

如果我理解正确,这将为您提供所需的输出:

select
  l1.typeid, 
  l1.status, 
  count(1) - (
    select count(1)
    from log l2
    where l2.typeid = l1.typeid and
          l2.date > l1.date
  )
from log l1
group by l1.typeid, l1.status;

选中此SQL Fiddle

TYPEID  STATUS      TOTAL
-----------------------------
ND0282  machine     1
ND0355  machine     1
ND0355  shopfloor   1
PF0180  shopfloor   1

答案 2 :(得分:0)

埃弗顿阿格纳最初发布了这个解决方案,但回复似乎已经消失,所以我正在添加它(略有修改)

select
  l1.typeid, 
  l1.status, 
  count(1) - (
    select count(1)
    from log l2
    where l2.typeid = l1.typeid and
          l2.`date` > l1.`date`
          AND l2.status != 'dieshop'
  ) as quant
from log l1
WHERE l1.status = 'dieshop' 
group by l1.typeid;