4

我有兩列如表:計數相等,有序的行集連續值

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列中。

如何計算從上一次操作開始的行中相同操作的數量?

連續相同動作的數量沒有限制,任何動作都可以是最後一個動作。此外,不同行爲的種類沒有限制:我只用了兩個來簡化示例數據。

對於此示例數據,我期望結果爲3.這是因爲最後一個操作是「b」,並且它連續出現3次。

我認爲解決方案可以結合窗口功能和WITH RECURSIVE條款,但我不知道該怎麼做。

回答

0

這應該這樣做。

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 

發現最後一排用不同的動作。

最外面的查詢查找該行之後的所有行。

+0

的偉大工程!非常感謝你救了我的一天:-) –

0

我給經典的間隙和孤島解決方案增加了一點小小的變化。
請注意ROW_NUMBER函數如何使用降序ORDER BY。

select count(*) 

from (select 

      action 
      ,row_number() over (     order by action_time desc) as rn 
      ,row_number() over (partition by action order by action_time desc) as rn_action 

     from mytab 
     ) t 

group by action 
     ,rn - rn_action 

having min(rn) = 1 
+0

這也是偉大的工程!謝謝! –

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)採取指數的優勢。

+0

查詢返回4,但應該返回3 :-( –

+0

那麼你可以使用'>',而不是'> ='。 –

0

改進方案

select count(*) 

from (select 

      action 
      ,row_number() over (     order by action_time desc) as rn 
      ,row_number() over (partition by action order by action_time desc) as rn_action 

     from mytab 
     ) t 

where rn = rn_action 
+0

它的工作原理。謝啦。 –