2017-02-16 182 views
0

這是我訪談中的一個問題。訪談問:將表login_log轉換爲last_login

在我們的系統中,每個登錄事件都登錄到login_log表中。它主要包含3列:

  • USER_ID
  • login_time
  • login_ip

我們現在36000組的用戶和每個用戶已登錄的約100倍,平均所以有360萬行的這表。

然後我們要將此錶轉換爲另一個表,名爲last_login,並且只記錄每個用戶的最新登錄事件。它還包含3列:

  • USER_ID
  • last_login_time
  • last_login_ip

於是就有了這個新表不超過36,000行。

考生可以通過SQL或編程來解決這個問題。有些候選人只用一個SQL解決了它。

享受它!

UPDATE

提示:login_log可以具有AUTO_INCREMENT id作爲主鍵。所以最新登錄事件的最大值爲id。找到我剛纔的答覆後

回答

1

編輯更新的答案是不正確的

select 
    user_id 
    , max(login_time) last_login_time 
    , max(login_ip) last_login_ip 
from 
    (
     select 
      user_id 
      , login_time 
      , max(login_ip) login_ip 
     from 
      login_log 
     group by user_id, login_time 
    ) t -- this sub-query makes sure we have only one row for each user_id+login_time 
group by user_id; 

您可以通過此link

測試程序找到結果sqlFiddle.com - 建表:

create table login_log (
    user_id int not null 
    , login_time datetime not null 
    , login_ip int not null 
    , index(user_id) 
    , index(login_time) 
); 

insert into login_log 
values 
(1, '2017-02-17', 100) 
, (1, '2017-02-15', 200) 
, (2, '2017-02-17', 300) 
, (2, '2017-02-14', 400) 
, (2, '2017-02-17', 500); 

我們需要一個子查詢(t)來打破情況 有多於一行給定user_id PLUS login_time 組合。子查詢可以確保只有單排 從它(一個與max(login_ip)

我剛纔的答覆忘記這樣的極端情況,因此 是不正確的出現。

+0

添加另一個login_log行(2,'2017-02-17',500)並再試一次:-) – auntyellow

+0

@auntyellow - 這是一個很好的觀點。我已經在上面更新了我的答案。謝謝! – leeyuiwah