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),
);

group by と同様に、特定のタイプの最後の終了アクションが各一意のペアで発生するようにクエリを実行しようとしています(ただし、SQLite では、group by によって返されることが保証されている(subtype_a, subtype_b)行はわかりません)。

約 1MB の SQLite データベースでは、クエリに2 秒以上かかる場合がありますが、1 秒未満になるように高速化する必要があります (これは頻繁に呼び出されるため)。

クエリの例:

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

これは、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 に答える
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 に答える