1

我有一个如下定义的表...

CREATE table actions (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  end BOOLEAN,
  type VARCHAR(15) NOT NULL,
  subtype_a VARCHAR(15),
  subtype_b VARCHAR(15),
);

我正在尝试查询在每个唯一(subtype_a, subtype_b)对上发生的某种类型的最后一个结束操作,类似于 group by(除了 SQLite 没有说明group by 保证返回哪一行)。

在大约 1MB 的 SQLite 数据库上,我现在的查询可能需要两秒钟以上的时间,但我需要加快速度,使其不到一秒钟(因为这将被频繁调用)。

示例查询:

SELECT * FROM actions a_out 
WHERE id = 
  (SELECT MAX(a_in.id) FROM actions a_in 
   WHERE a_out.subtype_a = a_in.subtype_a 
     AND a_out.subtype_b = a_in.subtype_b 
     AND a_in.status IS NOT NULL 
     AND a_in.type = "some_type");

如果它有帮助,我知道所有独特的可能性(subtype_a,subtype_b)

例如:

(a,1)
(a,2)
(b,3)
(b,4)
(b,5)
(b,6)
4

3 回答 3

1

从版本 3.7.11 开始,SQLite保证在组中返回哪条记录:

形式的查询:“SELECT max(x), y FROM table”返回包含最大 x 值的同一行上的 y 值。

因此可以以更简单的方式实现:

SELECT *, max(id)
FROM actions
WHERE type = 'some_type'
GROUP BY subtype_a, subtype_b
于 2012-12-10T08:44:13.570 回答
0

这是不是更快?

select * from actions where id in (select  max(id) from actions where type="some_type" group by subtype_a, subtype_b);
于 2012-12-09T19:48:56.230 回答
0

这是greatest-in-per-groupStackOverflow 上经常出现的问题。

这是我解决它的方法:

SELECT a_out.* FROM actions a_out
LEFT OUTER JOIN actions a_in ON a_out.subtype_a = a_in.subtype_a 
    AND a_out.subtype_b = a_in.subtype_b
    AND a_out.id < a_in.id
WHERE a_out.type = "some type" AND a_in.id IS NULL

如果您在 (type, subtype_a, subtype_b, id) 上有一个索引,它应该运行得非常快。


另请参阅我对类似 SQL 问题的回答:

或者 Jan Kneschke 的这篇精彩文章:Groupwise Max

于 2012-12-09T19:59:24.910 回答