5

次のような2つの列を持つテーブルがあります。

CREATE TABLE actions (
  action_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "action" text NOT NULL
);

およびその中の次のデータ:

        action_time         | action 
----------------------------+--------
 2016-12-30 14:12:33.353269 | a
 2016-12-30 14:12:38.536818 | b
 2016-12-30 14:12:43.305001 | a
 2016-12-30 14:12:49.432981 | a
 2016-12-30 14:12:53.536397 | b
 2016-12-30 14:12:57.449101 | b
 2016-12-30 14:13:01.592785 | a
 2016-12-30 14:13:06.192907 | b
 2016-12-30 14:13:11.249181 | b
 2016-12-30 14:13:13.690897 | b
(10 rows)

action_time列に重複する値はないと想定できます。

最後のアクションから始めて、連続して行われた同じアクションの数をカウントするにはどうすればよいですか?

連続する同じアクションの数に制限はなく、任意のアクションが最後のアクションになる可能性があります。また、さまざまなアクションに制限はありません。例のデータを単純化するために、2 つだけを使用しました。

この例のデータでは、結果が 3 になると予想しています。これは、最後のアクションが「b」であり、3 回連続して発生したためです。

ウィンドウ関数と句を組み合わせて解決策を達成できると思いますが、そのWITH RECURSIVE方法がわかりません。

4

4 に答える 4

1

これでうまくいくはずです。

SELECT COUNT(*)
FROM actions
WHERE action_time > (
SELECT action_time
  FROM actions 
  WHERE action <> (SELECT action FROM actions ORDER BY action_time DESC LIMIT 1) 
ORDER BY action_time DESC LIMIT 1);

最も内側のクエリ

SELECT action FROM actions ORDER BY action_time DESC LIMIT 1

最後のアクションを決定します。

クエリ

SELECT action_time
  FROM actions 
  WHERE action <> (SELECT action FROM actions ORDER BY action_time DESC LIMIT 1) 
ORDER BY action_time DESC LIMIT 1

別のアクションで最後の行を見つけます。

最も外側のクエリは、その行の後のすべての行を検索します。

于 2016-12-30T20:26:05.003 に答える
0

これが思い浮かびます:

select count(*)
from t cross join
     (select t2.action
      from t t2
      order by action_time desc
      limit 1
     ) last
where t.action_time >= (select max(t2.action_time)
                        from t t2
                        where t2.action <> last.action
                       );

これにより、 のインデックスを利用できるはず(action_time, action)です。

于 2016-12-30T20:22:45.683 に答える