如何解决间隙和孤岛问题-对数据的连续运行进行分组以获取最大和最小日期
我有一个使用Oracle无法解决的空白问题。
我试图在连续的LOGIN_TIME
和PC_ID
序列中获得具有相同值的第一个和最后一个事件(USER_NAME
)。在此示例中,我想要MIN(LOGIN_TIME)
和MAX(LOGIN_TIME)
,但只希望在'jane'登录之前的前三个登录中使用。然后,我希望对'jane'使用相同的登录方式,依此类推。>
查询
SELECT
PC_ID,USER_NAME,LOGIN_TIME
FROM
LOGIN_AUDIT
WHERE PC_ID = 72
AND LOGIN_TIME BETWEEN '2020-08-10 00:00:00' AND '2020-08-18 00:00:00'
;
上述查询的输出如下:
| PC_ID | USER_NAME | LOGIN_TIME |
|-------|-----------|---------------------|
| 72 | bob | 2020-08-10 09:00:00 |
| 72 | bob | 2020-08-10 13:30:00 |
| 72 | bob | 2020-08-11 09:00:00 |
| 72 | jane | 2020-08-12 08:00:00 |
| 72 | jane | 2020-08-13 09:00:00 |
| 72 | jane | 2020-08-13 14:30:00 |
| 72 | bob | 2020-08-14 08:00:00 |
| 72 | bob | 2020-08-15 08:00:00 |
| 72 | bob | 2020-08-16 08:00:00 |
| 72 | bob | 2020-08-17 08:00:00 |
我正在寻找的输出是这样:
| PC_ID | USER_NAME | FIRST_LOGIN | LAST_LOGIN |
|-------|-----------|---------------------|---------------------|
| 72 | bob | 2020-08-10 09:00:00 | 2020-08-11 09:00:00 |
| 72 | jane | 2020-08-12 08:00:00 | 2020-08-13 14:30:00 |
| 72 | bob | 2020-08-14 08:00:00 | 2020-08-17 08:00:00 |
我们将不胜感激。
解决方法
解决这类间隙和孤岛问题的一种简单方法是行数差异法。考虑:
WITH cte AS (
SELECT t.*,ROW_NUMBER() OVER (PARTITION BY PC_ID ORDER BY LOGIN_TIME) rn1,ROW_NUMBER() OVER (PARTITION BY PC_ID,USER_NAME ORDER BY LOGIN_TIME) rn2
FROM yourTable t
)
SELECT
PC_ID,USER_NAME,MIN(LOGIN_TIME) AS FIRST_LOGIN,MAX(LOGIN_TIME) AS LAST_LOGIN
FROM cte
GROUP BY
PC_ID,(rn1 - rn2)
ORDER BY
MIN(LOGIN_TIME);
Demo
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。