2016-04-28 136 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 - 是;想自己試試它會不會更容易? –