SQL查询匹配特定的IP地址

时间:2018-07-24 22:08:43

标签: sql sql-server

我有一个数据表,如下所示:

IP             ACCESS_DATE
----------------------------
192.168.1.5    06/22/2018
192.168.1.5    06/20/2018
192.168.1.5    06/18/2018
192.168.1.7    06/22/2018
192.168.1.7    05/01/2018
192.168.1.212  06/22/2018
10.10.10.1     06/22/2018

这是SQL Server,因此不可能有inet ...

我的IP列定义为varchar(20)

我有一个查询,该查询列出了与该表中所有IP地址相关的最新日期,并且我认为它可以正常工作。但是,我似乎无法让它返回特定IP的结果。

这是有效的查询:

SELECT 
    t.IP, t.ACCESSS_DATE 
FROM
    (SELECT 
         IP, MAX(ACCESSS_DATE) AS ACCESSS_DATE
     FROM  
         USER_ACCESS_HISTORY
     GROUP BY
         IP) x 
JOIN 
    USER_ACCESS_HISTORY t ON x.IP = t.ip
                          AND x.ACCESSS_DATE = t.ACCESSS_DATE

但是如果我这样做:

SELECT 
    t.IP, t.ACCESSS_DATE 
FROM
    (SELECT 
         IP, MAX(ACCESSS_DATE) AS ACCESSS_DATE
     FROM
         USER_ACCESS_HISTORY
     GROUP BY IP) x 
JOIN 
    USER_ACCESS_HISTORY t ON x.IP = '192.168.1.5'
                          AND x.ACCESSS_DATE = t.ACCESSS_DATE

返回

192.168.1.5    06/22/2018
192.168.1.7    06/22/2018
192.168.1.212  06/22/2018

任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:1)

您的版本会获得所有ip,它们的日期与给定ip的最大日期相同。也就是说,它缺少x.ipt.ip相等的附加条件。

如果只需要ip和日期,则不需要外部查询-子查询会生成这两列。

我个人将使用相关的子查询:

select uah.*
from user_access_history uah
where uah.access_date = (select max(uah2.access_date)
                         from user_access_history uah2
                         where uah2.ip = uah.ip
                        );

您可以将where子句添加到外部查询中。

user_access_history(ip, access_date)上有索引,这应该比您的问题建议的版本要快。

答案 1 :(得分:1)

更改此内容

ON x.IP =t.ip

对此:

ON x.IP ='192.168.1.5'

打破了USER_ACCESS_HISTORY表和子查询之间的查询关系,因此不再有任何关联。您想要这个:

SELECT t.IP, t.ACCESSS_DATE 
FROM( 
    SELECT IP,MAX(ACCESSS_DATE) AS ACCESSS_DATE
    FROM USER_ACCESS_HISTORY
     GROUP BY IP
) x 
JOIN USER_ACCESS_HISTORY t ON x.IP =t.ip
    AND x.ACCESSS_DATE = t.ACCESSS_DATE
WHERE x.IP ='192.168.1.5'

这样可以保留关系,也可以将数据仅过滤到所需的IP。

即使看起来似乎比您需要的复杂得多(仅子查询就足够了),但我假设我们只是看到查询的精简版本来说明问题。我确实提出了它,以防您可以减少这样的查询:

SELECT IP, MAX(ACCESSS_DATE) AS ACCESSS_DATE
FROM USER_ACCESS_HISTORY
WHERE IP = '192.168.1.5'
GROUP BY IP 

答案 2 :(得分:1)

由于您已经知道IP,因此实际上不需要任何连接:

SELECT IP, MAX(ACCESSS_DATE) AS ACCESSS_DATE
from USER_ACCESS_HISTORY
where IP ='192.168.1.5'
group by IP

答案 3 :(得分:0)

根据Cetin Basoz的回答,获取最新日期的另一种替代方法是:

SELECT TOP 1 [ip], [access_date] FROM @ips WHERE [ip] = '192.168.1.5' ORDER BY [access_date] DESC;

我查看了时间统计信息,MAX和TOP都相同。但是,使用如此小的数据集是可以预期的。

您可以对实际数据执行以下操作,以查看执行速度更快的数据。

使用 TOP

SET STATISTICS TIME ON

SELECT TOP 1 [ip], [access_date] FROM @ips WHERE [ip] = '192.168.1.5' ORDER BY [access_date] DESC;

SET STATISTICS TIME OFF

使用 MAX

SET STATISTICS TIME ON

SELECT [ip], MAX( [access_date] ) AS access_date FROM @ips WHERE [ip] = '192.168.1.5' GROUP BY [ip];

SET STATISTICS TIME OFF