首页 > 解决方案 > 比较不同记录之间的两个日期

问题描述

我尝试在 Oracle DB 上构建的 SQL 查询存在问题。我需要找出在其他记录之前创建某些记录的情况。这听起来很简单,但我遇到了问题,我不知道为什么。

有一个包含用户详细事件的表,称为“USER_EVENTS”。我们发现了一个涉及在用户被激活之前删除用户的错误。我想获取所有有此错误的用户,所以如果我查看表格,我会看到如下内容:

表 USER_EVENTS

ID  EVENT_TYPE      EVENT_DATE  USER_ID
1   USER_DELETED    10/1/2019   5301
2   USER_ACTIVATED  9/1/2019    5301
3   USER_DELETED    5/1/2019    5302
4   USER_ACTIVATED  11/1/2019   5302
5   USER_DELETED    1/1/2019    5288
6   USER_DELETED    2/1/2019    5287
7   USER_CREATED    1/12/2018   5211
8   USER_NOTE       1/12/2018   5211

尝试了各种查询,我似乎无法匹配这两个,我知道它很愚蠢,我很抱歉。

查看上表,我想获取在 ACTIVATED 事件之前具有 DELETED 事件的那些包裹的 USERID。从图片中,我应该得到的回报是“5302”,它在 2019 年 5 月 1 日被删除,但在 2019 年 11 月 1 日被激活。

提前致谢!

PS - 请不要涉及命名约定或如何没有此错误等的设计问题,以上只是一个一般示例。

标签: sqldatabaseoracle

解决方案


您可以使用COUNT不需要您在表上执行自联接的分析功能。

甲骨文设置

CREATE TABLE USER_EVENTS ( ID, EVENT_TYPE, EVENT_DATE, USER_ID ) AS
SELECT 1, 'USER_DELETED',    DATE '2019-01-10', 5301 FROM DUAL UNION ALL
SELECT 2, 'USER_ACTIVATED',  DATE '2019-01-09', 5301 FROM DUAL UNION ALL
SELECT 3, 'USER_DELETED',    DATE '2019-01-05', 5302 FROM DUAL UNION ALL
SELECT 4, 'USER_ACTIVATED',  DATE '2019-01-11', 5302 FROM DUAL UNION ALL
SELECT 5, 'USER_DELETED',    DATE '2019-01-01', 5288 FROM DUAL UNION ALL
SELECT 6, 'USER_DELETED',    DATE '2019-01-02', 5287 FROM DUAL UNION ALL
SELECT 7, 'USER_CREATED',    DATE '2018-12-01', 5211 FROM DUAL UNION ALL
SELECT 8, 'USER_NOTE',       DATE '2018-12-01', 5211 FROM DUAL;

查询 1

SELECT *
FROM   (
  SELECT u.*,
         COUNT( CASE event_type WHEN 'USER_ACTIVATED' THEN 1 END )
           OVER (
             PARTITION BY user_id
             ORDER BY event_date
             ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
           ) AS num_activated
  FROM   USER_EVENTS u
)
WHERE  num_activated > 0
AND    event_type = 'USER_DELETED';

结果

ID | EVENT_TYPE   | EVENT_DATE | USER_ID | NUM_ACTIVATED
-: | :----------- | :--------- | ------: | ------------:
 3 | USER_DELETED | 05-JAN-19  |    5302 |             1

查询 2

如果您只想要受影响USER_ID的 s 那么您可以使用GROUP BYand HAVING

SELECT USER_ID
FROM   USER_EVENTS
GROUP BY USER_ID
HAVING MIN( CASE EVENT_TYPE WHEN 'USER_DELETED' THEN EVENT_DATE END )
         < MIN( CASE EVENT_TYPE WHEN 'USER_ACTIVATED' THEN EVENT_DATE END )

结果

| USER_ID |
| ------: |
| 5302 |

db<>在这里摆弄


推荐阅读