SQL根据最近的TimeStamp选择多个列

时间:2017-03-21 13:04:06

标签: sql tsql

给出具有以下结构的查询结果

enter image description here

我需要编写一个SQL查询来向我提供在ChangeDate之前发生的最接近的LogInTime的DeviceName,Software,CurrentUser,ChangeDate和LogInTime。

所以在上图中,我有三个值将被突出显示。下面的图片是我对SQL Query的期望。

enter image description here

请注意,该查询包含数十万条记录。任何1台服务器都可以有多个不同的软件和多个不同的用户需要根据所有这些事实分离结果。

以下是提取此信息的查询的编辑版本:

SELECT DeviceName
    , Software
    , CurrentUser
    , ChangeDate
    , (
        CASE 
            WHEN ActionCode = 39
                THEN actiondate
            ELSE NULL
            END
        ) AS LogInTime
FROM dbo.Info
RIGHT JOIN (
    SELECT DISTINCT c.computer_idn
        , c.DeviceName
        , h.ChangeDate
        , h.newstr AS Software
    FROM dbo.history AS H
    LEFT JOIN dbo.Computer AS c
        ON c.computer_idn = h.computer_idn
    WHERE h.tablename LIKE 'AppSoftwareSuites'
        AND ChangeDate > DATEADD(day, - 7, GETDATE())
    ) AS t1
    ON t1.computer_idn = Info.computer_idn
WHERE actioncode = 39

我对如何获得我想要的结果感到困惑,我真的不想用PowerShell / C#创建一个宏或程序,所以非常感谢任何帮助!

这是有效的!

WITH query_cte A
 AS (SELECT devicename, 
            software, 
            currentuser, 
            changedate, 
            logintime, 
            Rank() 
              OVER( 
                partition BY changedate 
                ORDER BY logintime DESC) AS login_rank 
FROM(
SELECT DeviceName
    , Software
    , CurrentUser
    , ChangeDate
    , (
        CASE 
            WHEN ActionCode = 39
                THEN actiondate
            ELSE NULL
            END
        ) AS LogInTime
FROM dbo.Info
RIGHT JOIN (
    SELECT DISTINCT c.computer_idn
        , c.DeviceName
        , h.ChangeDate
        , h.newstr AS Software
    FROM dbo.history AS H
    LEFT JOIN dbo.Computer AS c
        ON c.computer_idn = h.computer_idn
    WHERE h.tablename LIKE 'AppSoftwareSuites'
        AND ChangeDate > DATEADD(day, - 7, GETDATE())
    ) AS t1
    ON t1.computer_idn = Info.computer_idn
WHERE actioncode = 39
                )AS t3 
     WHERE  logintime <= changedate) 
SELECT * FROM   query_cte WHERE  login_rank = 1 

2 个答案:

答案 0 :(得分:1)

您需要使用ROWRANK之类的内容,按三个返回字段进行分区,然后按LoginTime DESC排序。

在CTE中执行大量查询意味着您可以过滤掉不是最新LoginTime的所有内容。

WITH query_cte AS (
    Select DeviceName,  Software, CurrentUser,  ChangeDate,
    (case when ActionCode = 39 then actiondate else  null end) as LogInTime,
    ROWRANK OVER(PARTITION BY ChangeDate ORDER BY LoginTime DESC) as login_rank
    from dbo.Info right outer join 
    (select distinct c.computer_idn, c.DeviceName, h.ChangeDate, h.newstr as Software
    from dbo.history as H
    left outer join dbo.Computer as c on c.computer_idn = h.computer_idn
    where h.tablename like 'AppSoftwareSuites' 
    AND ChangeDate > DATEADD(day, -7, GETDATE()) ) as t1
    on t1.computer_idn = Info.computer_idn
    WHERE actioncode =  39
    AND LoginTime < ChangeDate
)
SELECT * from query_cte WHERE login_rank = 1
  • 警告:来自内存的代码,我会尝试稍后进行模拟以测试它。

答案 1 :(得分:0)

为了获得良好的帮助,你应该展示表格的关系

SELECT DeviceName,Software,CurrentUser,ChangeDate,LogInTime FROM tableName LogInTime&lt; = ChangeDate