高级农民
- 积分
- 4176
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2017-1-22
- 最后登录
- 1970-1-1
|
1454. Active Users
Medium
Topics
conpanies icon
Companies
SQL Schema
Pandas Schema
Table: Accounts
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
+---------------+---------+
id is the primary key (column with unique values) for this table.
This table contains the account id and the user name of each account.
Table: Logins
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| login_date | date |
+---------------+---------+
This table may contain duplicate rows.
This table contains the account id of the user who logged in and the login date. A user may log in multiple times in the day.
Active users are those who logged in to their accounts for five or more consecutive days.
Write a solution to find the id and the name of active users.
Return the result table ordered by id.
The result format is in the following example.
Example 1:
Input:
Accounts table:
+----+----------+
| id | name |
+----+----------+
| 1 | Winston |
| 7 | Jonathan |
+----+----------+
Logins table:
+----+------------+
| id | login_date |
+----+------------+
| 7 | 2020-05-30 |
| 1 | 2020-05-30 |
| 7 | 2020-05-31 |
| 7 | 2020-06-01 |
| 7 | 2020-06-02 |
| 7 | 2020-06-02 |
| 7 | 2020-06-03 |
| 1 | 2020-06-07 |
| 7 | 2020-06-10 |
+----+------------+
Output:
+----+----------+
| id | name |
+----+----------+
| 7 | Jonathan |
+----+----------+
Explanation:
User Winston with id = 1 logged in 2 times only in 2 different days, so, Winston is not an active user.
User Jonathan with id = 7 logged in 7 times in 6 different days, five of them were consecutive days, so, Jonathan is an active user.
Follow up: Could you write a general solution if the active users are those who logged in to their accounts for n or more consecutive days?
思路
这是**连续区间(gaps and islands)**问题加一层去重。要找连续登录至少 5 天的用户,有两个细节:
同一天可能登录多次:Logins 允许重复行,示例里用户 7 在 06-02 登录了两次。按"天"算连续,所以要先对 (id, login_date) 去重,否则行号会虚增,连续性判断就错了。
连续的判断:对每个用户,把去重后的日期排序并编号 rn = 1, 2, 3, ...。日期每增加 1 天,行号也增加 1,所以 日期 - rn 保持不变。中间断一天,差值就变了。差值相同的日期属于同一段连续登录,某一段的天数 ≥ 5,这个用户就是活跃用户。- # Write your MySQL query statement below
- WITH d AS (
- SELECT DISTINCT id, login_date
- FROM Logins
- ),
- g AS (
- SELECT
- id,
- login_date,
- DATE_SUB(
- login_date,
- INTERVAL ROW_NUMBER() OVER (PARTITION BY id ORDER BY login_date) DAY
- ) AS grp
- FROM d
- ),
- active AS (
- SELECT DISTINCT id
- FROM g
- GROUP BY id, grp
- HAVING COUNT(*) >= 5
- )
- SELECT a.id, a.name
- FROM Accounts a
- JOIN active v ON a.id = v.id
- ORDER BY a.id;
复制代码 |
|