1

「非アクティブ時間」に基づいて SQL のいくつかの行を GROUP BY したいと思います。つまり、ユーザー セッションを認識するために、タイムスタンプ間に大きなギャップがあることに注意してください。

sqlite データベースに次のアクション テーブルがあるとします。

_actions_
| id | userID | timestamp | actionType |

これで、すべてのユーザー アクションとそのタイプを時間、月、年などでグループ化して表示できます。

SELECT 
    userID, strftime('%H', timestamp), group_concat(actionType)
FROM 
    actions 
GROUP BY userID, strftime('%H', timestamp);

しかし、それは私が完全に望むものではありません。このことを考慮:

| 1 | 333 | 13.11.2014-20:59 | action6 |
| 2 | 333 | 13.11.2014-21:01 | action3 |
| 3 | 333 | 13.11.2014-21:47 | action5 |

私の例は行 1 と行 2+3 にマージされますが、セッション タイムアウトを 30 分と仮定すると、行 1+2 と行 3 を取得する必要があります。SQL のアイデアはありますか?

current_timestamp - last_timestamp > 30minの場合、データベースとR、Pandasなどをロードして各ユーザーを確認できますが、これは本当に行くべきですか?

4

1 に答える 1

0

行がセッションの最初の行である場所を計算するには、過去 30 分間に他の行が存在するかどうかを確認します。

SELECT *,
       NOT EXISTS (SELECT 1
                   FROM actions AS prev
                   WHERE userid = actions.userid
                     AND timestamp < actions.timestamp
                     AND timestamp >= datetime(actions.timestamp, '-30 minutes')
                  ) AS first
FROM actions;

id          userid      timestamp         actiontype  first     
----------  ----------  ----------------  ----------  ----------
1           333         2014-11-13 20:59  action6     1         
2           333         2014-11-13 21:01  action3     0         
3           333         2014-11-13 21:47  action5     1         

しかし、彼はグループ化に直接役立つわけではありません。グループ内のすべての行に対して一意の値が必要です。

グループの最初の行の ID を取得しましょう。現在の行のグループのこの最初の行を見つけるために、あるグループの最初の行であり、現在の行の後ではない最後の行を取得します。

SELECT *,
       (SELECT id
        FROM actions AS first
        WHERE userid = actions.userid
          AND timestamp <= actions.timestamp
          AND NOT EXISTS (SELECT 1
                          FROM actions AS prev
                          WHERE userid = first.userid
                            AND timestamp < first.timestamp
                            AND timestamp >= datetime(first.timestamp, '-30 minutes')
                         )
        ORDER BY timestamp DESC
        LIMIT 1
       ) AS sessionid
FROM actions;

id          userid      timestamp         actiontype  sessionid 
----------  ----------  ----------------  ----------  ----------
1           333         2014-11-13 20:59  action6     1         
2           333         2014-11-13 21:01  action3     1         
3           333         2014-11-13 21:47  action5     3         

このクエリを効率的にするには、timestamp列にインデックスを付ける必要があります。

于 2014-11-12T21:20:12.340 に答える