2016-04-28 22 views
1

私はテーブル 'LIST_USERS'を持っています。SQL select case group by

表の説明 -

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; 
+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 - はい。自分で試してみるのは簡単だったでしょうか? –