选择不同的行时提供其他数据

时间:2010-07-21 16:39:57

标签: sql-server-2005 tsql subquery

我有一张来自Active Directory的登录事件表。这些事件中的一种是机器登录,其中包括登录的机器的IP地址。这很方便,因为它提供了一种时间戳方式来确定在给定时间什么IP上的机器。我正在尝试构建一个查询,它会给我一个时间戳列表,列出机器何时首次登录到IP(感谢DHCP,IP是可变的)。

如果该机器所持有的IP地址,则只返回列表的查询很简单。

SELECT DISTINCT IP
FROM EventStream
WHERE (Machine='$Machine')

我知道'select distinct'是一个非最佳查询,这就是为什么我在寻找更好的东西。这可能包括子查询,我对此知之甚少。在这种情况下不提供“Distinct”会返回一个最多包含2000行的表,因此正在选择大量数据而不使用它们。

我真正想要的是一种表达查询的方法,这样我就可以得到一个时间戳列表,列出机器首次出现在IP地址上的时间。我可以通过在第一个结果上迭代此查询来伪造它:

SELECT TOP 1 DateTime
FROM EventStream
WHERE (Machine='$Machine' and IP='$IP')
ORDER BY DateTime

我很确定这两者可以组合成一个统一的查询。这是可能的,还是我应该坚持使用应用程序逻辑来提供我正在寻找的东西?

2 个答案:

答案 0 :(得分:2)

只是要确认一下,你想看到机器在第一次出现在每个IP地址时使用的所有IP地址吗?

如果是这样,你应该可以这样做:

SELECT IP, max(DateTime) as DateTime
FROM EventStream
WHERE Machine='$Machine'
GROUP BY IP

答案 1 :(得分:1)

派对有点晚了,但是如果你不需要先找到IP然后循环找到你想要的信息,这就可以做你想做的事情:

SELECT  Machine,
        IP,
        Date
FROM    (SELECT Machine,
                IP,
                Date,
                ROW_NUMBER() OVER (PARTITION BY Machine, IP ORDER BY Date DESC) RN
         FROM   EventStream) EventStream
WHERE   RN = 1

这将为您提供Eventstream中所有计算机的所有IP,并根据日期列仅返回每个计算机的最后日期(ORDER BY Date DESC)。如果您想要第一个日期,只需从订单中删除“DESC”。