簡體   English   中英

選擇最后N個唯一記錄mysql

[英]Select last N unique records mysql

我有一個“會話”表,其他字段中包含以下字段:

int int(11),
user_id int(11),
login_date timestamp,
ip varchar(15)

我想為每個用戶選擇最后一個login_date和最后三個唯一的ips。 我怎樣才能以優雅的方式做到這一點?

我找到了一個解決方案,但它非常非常非常丑陋,無效,耗時並且涉及到mysql和bash腳本的混合。 我怎么能只在MySQL中這樣做?

PS該表有cca 430萬行。

一些示例數據: http//sqlfiddle.com/#!2 / e9ddd

花了很多時間從SQL SERVER轉換MYSQL

我在查詢上工作以獲得更好的性能

select 
user_id,
max(cast(login_date as datetime)),
group_concat(distinct ip order by login_date desc SEPARATOR  ' , ')
from 
(
SELECT 
  user_id,
  login_date,
  ip,
  CASE user_id 
   WHEN @curType 
    THEN @curRow := @curRow + 1 
    ELSE @curRow := 1 AND @curType := user_id 
  END as sequence
FROM sessions, (SELECT @curRow := 0, @curType := '') r
ORDER BY user_id asc,login_date desc
)t
where sequence<4
group by user_id

SQL FIDDLE

這將為您提供每個user_id的最后日期

SELECT s1.* FROM sessions s1 
LEFT OUTER JOIN sessions s2
ON s1.user_id = s2.user_id AND s1.login_date < s2.login_date
WHERE s2.user_id IS NULL

這將獲得用於每個user_id的唯一IP

SELECT user_id, GROUP_CONCAT(DISTINCT(ip)) FROM sessions GROUP BY user_id

然后你可以把它們混合起來,把它們放在一起會對資源有點沉重,但我認為它是可行的。

祝好運!

http://sqlfiddle.com/#!2/bb209/71

你可以這樣做:

SELECT * FROM (
  SELECT 
    user_id
    ,ip, 
    ,login_date
    ,IF(@user_id = SESSION_GRUOPED.user_id, @rownum:=@rownum+1, @rownum:=1 ) as row_id
    ,(@user_id:= SESSION_GRUOPED.user_id) as group_id
  FROM (
    SELECT user_id, ip, max(login_date) login_date FROM SESSION group by user_id, ip order by user_id, login_date desc
  ) SESSION_GRUOPED 
    JOIN  (SELECT @rownum := 0) r
    JOIN  (select @user_id := 0) u
) RESULT
WHERE row_id < 4;

查詢的關鍵是這部分

SELECT user_id, ip, max(login_date) login_date FROM SESSION group by user_id, ip order by user_id, login_date desc

多虧了它,你得到每個用戶給定ip上次登錄的信息。

然后將其包裝在組中設置結果編號,然后將結果限制為小於4的結果,因為單個用戶只需要三個結果。

注意:如果將row_id <4更改為row_id = 1,則您將擁有最新的用戶登錄名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM