时间:2016-04-28 18:55:05

标签: sql oracle11g oracle-sqldeveloper sql-function

我有一张桌子'LIST_USERS'。

表格说明 -

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

条件 - 我需要根据最大LOGIN_DATE从'LIST_USERS'表中获取USER_ID和LOGIN_ID。如果LOGIN_DATE为null,我需要根据最大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;

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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()首先获取登录日期,如果为空,则返回创建日期(或者您可以使用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