[英]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
這將為您提供每個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
然后你可以把它們混合起來,把它們放在一起會對資源有點沉重,但我認為它是可行的。
祝好運!
你可以這樣做:
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.