Access SQL - 如何获取最新记录和时间戳之前的最后一条记录?

时间:2014-07-03 13:10:03

标签: sql ms-access

因为我在SQL方面做得不好,所以我决定第一次在这里发帖,因为我坚持创建一个查询几天,并且无法弄清楚如何正确使用它。 我有一个表,它以历史形式保存信息,以根据时间戳保持以前的IP地址状态与端口。 我的Java程序正在使用此表来处理IP地址的状态。 另外,我需要在ACTION DATE之前显示最后一次出现的最后一次出现状态。

DST IP         | DST PORT | ACTION DATE         | STATUS
-------------------------------------------------------
0.0.0.0        |  80      | 2014.06.12. 9:22:27 | 4
10.146.203.184 |  80      | 2014.06.10. 8:43:51 | 4
10.146.203.184 |  80      | 2014.06.10. 8:43:41 | 4
10.146.203.184 |  80      | 2014.06.10. 8:28:35 | 0

我需要过滤表格,根据最新状态显示唯一的IP地址。

我可以这样做:

SELECT 
    T1.[DST IP], T1.[DST PORT], MAX(T1.[ACTION DATE]) AS LASTDATE 
FROM 
    IP_BLOCK_LIST AS T1 
GROUP BY 
    T1.[DST IP], T1.[DST PORT]

但是我还需要在给定IP和端口的ACTION DATE之前显示最后一次作为LAST OCCURRENCE。所以我应该得到类似上述内容:

DST IP       | DST PORT  | ACTION DATE         | STATUS | **LAST OCCURRENCE** 

0.0.0.0        |80       | 2014.06.12. 9:22:27 | 4      | 2014.06.12. 9:22:27 

10.146.203.184 |80       | 2014.06.10. 8:43:51 | 4      | 2014.06.10. 8:43:41

我可以从表中获取最后一条记录:

SELECT TOP 1 [ACTION DATE]
FROM (SELECT TOP 2 * FROM IP_BLOCK_LIST ORDER BY [ACTION DATE] DESC)  AS T3
ORDER BY T3.[ACTION DATE]

但不是每个最新发生的ip-port。

获得一些帮助会很棒,因为它让我想不通。

谢谢。

的Istvan

更新

我终于想出了这个问题:

SELECT T1.[DST IP], T1.RANGE, T1.[DST PORT], T1.STATUS, T1.NOTE, T1.SOURCE, T1.[BLOCK DIRECTION], T1.[ACTION DATE] AS [PERFORM DATE], Q1.[LAST OCCURRENCE] FROM IP_BLOCK_LIST AS T1 LEFT JOIN (SELECT Q2.[DST IP], Q2.[DST PORT], Max(Q2.[ACTION DATE]) AS [MaxOfACTION DATE], Min(Q2.[ACTION DATE]) AS [LAST OCCURRENCE] FROM (SELECT T2.[DST IP], T2.[DST PORT], T2.[ACTION DATE] FROM IP_BLOCK_LIST AS T2 WHERE (T2.[ACTION DATE]) In (SELECT TOP 2 T3.[ACTION DATE] FROM IP_BLOCK_LIST AS T3 WHERE T2.[DST IP] = T3.[DST IP] AND T2.[DST PORT] = T3.[DST PORT] ORDER BY [ACTION DATE] DESC )) AS Q2 GROUP BY Q2.[DST IP], Q2.[DST PORT]) AS Q1 ON (T1.[DST PORT] = Q1.[DST PORT]) AND (T1.[DST IP] = Q1.[DST IP]) WHERE (T1.[ACTION DATE]=[Q1].[MaxOfACTION Date])

可以简化一下吗?

2 个答案:

答案 0 :(得分:0)

您可以使用相关子查询来执行此操作:

select bl.*
from ip_block_list bl
where bl.[ACTION DATE] in (select top 2 bl2.[ACTION DATE]
                           from ip_block_list bl
                           where bl2.[DST IP] = bl.[DST IP] and
                                 bl2.[DST PORT] = bl.[DST PORT]
                           order by [ACTION DATE] desc
                          );

请注意,对于tie,这将返回给定IP的两个以上记录。

答案 1 :(得分:0)

您可以尝试加入子查询。 我不知道这是否是最佳解决方案,我只是将您的查询合并到一个查询中

SELECT 
    T1.[DST IP], T1.[DST PORT], MAX(T1.[ACTION DATE]) As ACTIONDATE, MAX(T3.[ACTION DATE]) AS LASTDATE 
FROM 
    IP_BLOCK_LIST AS T1 
LEFT JOIN 
(
SELECT TOP 1 
_sub.[ACTION DATE], _sub.[DST IP]
FROM (SELECT TOP 2 [ACTION DATE], [DST IP] FROM IP_BLOCK_LIST) AS _sub) 
AS T3 ON T1.[DST IP] = T3.[DST IP]
GROUP BY 
T1.[DST IP], T1.[DST PORT]