2016-04-28 79 views
1

我有一个表'LIST_USERS'。SQL选择案例组由

表描述 -

USER_ID  NUMBER(8) 
LOGIN_ID  VARCHAR2(8) 
CREATE_DATE TIMESTAMP(6) 
LOGIN_DATE TIMESTAMP(6) 

表数据 -

USER_ID  LOGIN_ID CREATE_DATE  LOGIN_DATE 
--------------------------------------------------- 
101   test1  04/24/2016  null 
102   test1  04/24/2016  04/29/2016 
103   test2  04/25/2016  null 
104   test2  04/26/2016  null 
105   test3  04/27/2016  04/28/2016 
106   test3  04/27/2016  04/29/2016 
107   test4  04/28/2016  04/29/2016 
987   test5  04/29/2016  null 
109   test5  04/29/2016  null 
108   test5  04/29/2016  04/29/2016 

条件 - 我需要获取USER_ID和LOGIN_ID基于最大LOGIN_DATE的 'LIST_USERS' 表。如果LOGIN_DATE为空,我需要根据最大CREATE_DATE获取记录。

我需要得到下面的结果 -

USER_ID  LOGIN_ID 
--------------------- 
102   test1 
104   test2 
106   test3 
107   test4 
108   test5 

我使用下面的查询。但它只会给我LOGIN_ID和'Login_Or_Create_Date',但我需要USER_ID和LOGIN_ID。有办法可以得到USER_ID以及上面显示的结果吗?

select LOGIN_ID, 
     (case when max(LOGIN_DATE) is null then max(CREATE_DATE) 
      else max(LOGIN_DATE) end) as Login_Or_Create_Date 
from LIST_USERS; 
+1

会发生什么,如果用户登录两次在同一天?你想保留哪一个? –

+0

应用程序中存在一个错误,导致上述情况。基本上我需要保留最新的记录并清理其他记录。 – user2893856

回答

3

试试这个:

SELECT USER_ID, LOGIN_ID 
FROM (
    SELECT USER_ID, LOGIN_ID, 
     ROW_NUMBER() OVER (PARTITION BY LOGIN_ID 
          ORDER BY COALESCE(LOGIN_DATE, CREATE_DATE) DESC) AS rn 
FROM LIST_USERS) t 
WHERE t.rn = 1 
+0

我调整了表格中的数据。它会与上述查询一起工作吗? – user2893856

+0

这也是我最后提出的查询。 –

+0

@ user2893856我无法想象您的实际数据集是什么样子。你可以试试看看查询产生了什么结果。 –

2

听起来像是keep dense_rank工作:

select min(user_id) keep (dense_rank last order by coalesce(login_date, create_date)) 
    as user_id, 
    login_id 
from list_users 
group by login_id 
order by user_id; 

last保持与最新的登录记录/创建日期; coalesce()首先获取登录日期,如果该值为null(或者您可以使用nvl()而不是当然),则会返回到创建日期。你也可以做first并按desc排序 - 结果是一样的(如果没有空值,看起来应该不是),但last感觉更直观,当你想要我认为最新的日期时。 演示使用一个CTE数据:

with list_users(user_id, login_id, create_date, login_date) as (
    select 101, 'test1', date '2016-04-24', null from dual 
    union all select 102, 'test1', date '2016-04-24', date '2016-04-29' from dual 
    union all select 103, 'test2', date '2016-04-25', null from dual 
    union all select 104, 'test2', date '2016-04-26', null from dual 
    union all select 105, 'test3', date '2016-04-27', date '2016-04-28' from dual 
    union all select 106, 'test3', date '2016-04-27', date '2016-04-29' from dual 
    union all select 107, 'test4', date '2016-04-28', date '2016-04-29' from dual 
) 
select min(user_id) keep (dense_rank last order by coalesce(login_date, create_date)) 
    as user_id, 
    login_id 
from list_users 
group by login_id 
order by user_id; 

    USER_ID LOGIN 
---------- ----- 
     102 test1 
     104 test2 
     106 test3 
     107 test4 

并与修改后的数据:

with list_users(user_id, login_id, create_date, login_date) as (
    select 101, 'test1', date '2016-04-24', null from dual 
    union all select 102, 'test1', date '2016-04-24', date '2016-04-29' from dual 
    union all select 103, 'test2', date '2016-04-25', null from dual 
    union all select 104, 'test2', date '2016-04-26', null from dual 
    union all select 105, 'test3', date '2016-04-27', date '2016-04-28' from dual 
    union all select 106, 'test3', date '2016-04-27', date '2016-04-29' from dual 
    union all select 107, 'test4', date '2016-04-28', date '2016-04-29' from dual 
    union all select 987, 'test5', date '2016-04-29', null from dual 
    union all select 109, 'test5', date '2016-04-29', null from dual 
    union all select 108, 'test5', date '2016-04-29', date '2016-04-29' from dual 
) 
select min(user_id) keep (dense_rank last order by coalesce(login_date, create_date)) 
    as user_id, 
    login_id 
from list_users 
group by login_id 
order by user_id; 

    USER_ID LOGIN 
---------- ----- 
     102 test1 
     104 test2 
     106 test3 
     107 test4 
     108 test5 
+0

Keep对我来说是新的 –

+0

我调整了表格中的数据。它会与上述查询一起工作吗? – user2893856

+0

@ user2893856 - 是;想自己试试它会不会更容易? –