2012-01-05 41 views
3

由於我下面的表結構:查詢,選擇所有行自去年成功

enter image description here

我試圖建立一個查詢,將返回數失敗的登錄嘗試每個IP 因爲在過去一小時內最後一次成功登錄該IP。例如,你會注意到在過去一個小時內,來自單個IP的多個失敗嘗試(0),但自上次成功登錄(#145)以來,只有1次(#146),這就是我想要返回。

該查詢也應該是動態的並返回分組IP的行。

到目前爲止,這是我,但我認爲@ipa正在恢復NULL

SELECT COUNT(*) tries, @ipa := login_ip 
FROM login_log 
WHERE login_id > (
    SELECT MAX(login_id) 
    FROM login_log 
    WHERE login_success = 1 
    AND login_ip = @ipa 
) 
AND login_success = 0 
AND login_date > NOW() - 3600 
GROUP BY login_ip 
ORDER BY tries DESC; 

感謝

+0

在使用前似乎沒有設置「@ ipa」。 – 2012-01-05 20:14:54

回答

2

別名表,並嘗試這種方式,爲您的@ipa變量無所事事爲您提供:

SELECT COUNT(1) tries, l.login_ip 
FROM login_log l 
WHERE login_id > (
    SELECT MAX(login_id) 
    FROM login_log l2 
    WHERE l2.login_success = 1 
    AND l2.login_ip = l.login_ip 
) 
AND login_success = 0 
AND login_date > NOW() - 3600 
GROUP BY login_ip 
ORDER BY tries DESC; 

此外,您可以用join做到這一點:

select 
    count(1) tries, 
    log1.login_ip 
from 
    login_log log1 
    inner join (
     select 
      login_ip, 
      max(login_date) as max_date 
     from 
      login_log 
     where 
      login_success = 1 
     group by 
      login_ip 
    ) log2 on 
     log1.login_ip = log2.login_ip 
where 
    log1.login_success = 0 
    and log1.login_date > NOW() - 3600 
    and log1.login_date > log2.max_date 
group by 
    login_ip 
order by tries desc 

你可以嘗試兩種方式,看看哪一種更快。

+0

在第二行的第8行末尾缺少一個逗號,但除此之外它的作用!而且速度更快,因爲我不必做子查詢。謝謝! – 2012-01-05 20:36:16

+0

@stevether - 啊,對於錯過的逗號感到抱歉。修正:)並澄清,你正在做一個子查詢,只是不相關的子查詢。不同之處在於前者只運行一次,而後者每行運行*,這可能需要一點時間。 – Eric 2012-01-05 20:37:47

+0

如果從來沒有成功登錄過IP,我該如何才能使其工作?它只是不返回行,但它應該。 – 2012-01-05 20:50:55