2017-04-04 263 views
1


dbo.AllApps记录所有已运行的可执行文件,它具有一个名为ApplicationHash的列,该列存储exe的哈希值。
因此,如果exe已经运行了10次,表中将有10个条目具有相同的信息但时间戳不同。
我想生成一个报告,它只会返回10行中的1行(包括所有列时间,名称,desc ...)和一个额外的列,它们将提供执行exe的次数。
有什么建议吗?SQL - 仅返回匹配的第一行

`/* !!!!!DEFINE START AND END DATE FOR REPORT HERE!!!!!*/ 
DECLARE @StartDate DATETIME = 2017-01-01 
DECLARE @EndDate DATETIME = 2017-01-02` 

`/* Checks if the temp table #PCount exist and deletes the table if it does */ 
IF OBJECT_ID('tempdb..#PCount') IS NOT NULL 
BEGIN 
DROP TABLE #PCount 
END` 

`/* Performs a COUNT on the ApplicationHash entries */ 
SELECT ApplicationHash, COUNT(ApplicationHash) AS ProcessCount 
INTO #PCount 
FROM dbo.AllApps 
WHERE 
TokenType = 'Elevated' 
AND ApplicationType != 'COM Class' 
AND ApplicationType != 'ActiveX Control' 
AND ProcessStartTime >= @StartDate 
AND ProcessStartTime < @EndDAte 
GROUP BY ApplicationHash` 

`/* Pulls up the actual report and inserts the count value for the ApplicationHash */ 
SELECT #PCount.ProcessCount, 
dbo.AllApps.ApplicationHash, 
dbo.AllApps.ProcessStartTime, 
dbo.AllApps.ApplicationType, 
dbo.AllApps.Description, 
dbo.AllApps.Publisher, 
dbo.AllApps.ProductName, 
dbo.AllApps.ProductVersion, 
dbo.AllApps.EventDescription, 
dbo.AllApps.CommandLine, 
dbo.AllApps.FileName 
FROM #PCount, dbo.AllApps 
WHERE dbo.AllApps.ApplicationHash = #PCount.ApplicationHash 
AND TokenType = 'Elevated' 
AND ApplicationType != 'COM Class' 
AND ApplicationType != 'ActiveX Control' 
AND ProcessStartTime >= @StartDate 
AND ProcessStartTime < @EndDate 
ORDER BY ProcessStartTime DESC` 
+0

在sql server中,您只需以'TOP 1'作为字段列表的前缀来获取第一行。 – Hogan

+0

而在10行中,您希望读取哪个时间,名称,desc等? – dotNET

+0

@Hogan - 如果你只想要第一行,而不是所有'ApplicationHash'值的第一行,这才是真实的。 –

回答

0

使用top with tiesrow_number()可以获得最近的ProccessStartTimecount(*) over()的行为ProcessCount

注意:此解决方案不需要临时表。如果两个查询的where标准不同,那么这将是一个不同的故事。

更新:如果不知道更多的关于数据类型和一个唯一的id的存在下,在此表中的行,我已经添加了一个case表达以包括ProcessStartTime到分区时ApplicationHash = <None>,否则一个常数(@StartDate) 。

declare @StartDate datetime = '20170101'; 
declare @EndDate datetime = '20170102'; 

select top 1 with ties 
    ProcessCount = count(*) over (
     partition by ApplicationHash 
     , case 
      when ApplicationHash = '<None>' 
      then ProcessStartTime 
      else @StartDate 
      end 
     order by ProcessStartTime desc 
    ) 
    , ApplicationHash 
    , ProcessStartTime 
    , ApplicationType 
    , Description 
    , Publisher 
    , ProductName 
    , ProductVersion 
    , EventDescription 
    , CommandLine 
    , FileName 
from dbo.AllApps aa 
where TokenType = 'Elevated' 
    and ApplicationType != 'com Class' 
    and ApplicationType != 'ActiveX Control' 
    and ProcessStartTime >= @StartDate 
    and ProcessStartTime < @EndDate 
order by row_number() over (
    partition by ApplicationHash 
    , case 
     when ApplicationHash = '<None>' 
     then ProcessStartTime 
     else @StartDate 
     end 
    order by ProcessStartTime desc 
) 
+0

这工作谢谢,这可以进一步修改以下? “ApplicationHash”列有一些条目的值为“”,这些是没有计算哈希值的情况下,是否可以列出ApplicationHash =“”的所有行与您提供的代码结果的组合? – AlexJP

+0

@AlexJP在这张桌子上有独特的ID吗? – SqlZim

+0

这工作谢谢,这可以进一步修改以下? “ApplicationHash”列有一些值为“”的条目,这些是不计算散列值的情况。是否有可能将ApplicationHash =“”的所有行与您提供的代码结果一起列出? – AlexJP

1

最简单的方法是使用一个CTE和ROW_NUMBER:

;with cte as 
(
SELECT ROW_NUMBER() OVER(PARTITION BY ApplicationHash ORDER BY ProcessStartTime) as rn, 
#PCount.ProcessCount, 
dbo.AllApps.ApplicationHash, 
dbo.AllApps.ProcessStartTime, 
dbo.AllApps.ApplicationType, 
dbo.AllApps.Description, 
dbo.AllApps.Publisher, 
dbo.AllApps.ProductName, 
dbo.AllApps.ProductVersion, 
dbo.AllApps.EventDescription, 
dbo.AllApps.CommandLine, 
dbo.AllApps.FileName 
FROM #PCount 
INNER JOIN dbo.AllApps ON dbo.AllApps.ApplicationHash = #PCount.ApplicationHash 
WHERE TokenType = 'Elevated' 
AND ApplicationType != 'COM Class' 
AND ApplicationType != 'ActiveX Control' 
AND ProcessStartTime >= @StartDate 
AND ProcessStartTime < @EndDate 
) 

SELECT ProcessCount, 
     ApplicationHash, 
     ProcessStartTime, 
     ApplicationType, 
     Description, 
     Publisher, 
     ProductName, 
     ProductVersion, 
     EventDescription, 
     CommandLine, 
     FileName 
FROM CTE 
WHERE rn = 1 

请注意,我已经改变了你的隐式连接到一个明确的加入。
阅读Aaron Bertrand的Bad habits to kick : using old-style JOINs找出原因。

+0

这是行不通的,我得到以下错误:Msg 1033,Level 15,State 1,Line 26 ORDER BY子句在视图,内联函数,派生表,子查询和公用表表达式,除非还指定了TOP,OFFSET或FOR XML。 – AlexJP

+0

是的,已将其从我的答案中删除。 –

+0

部分工作,它返回1行而不是44行,它应该。 – AlexJP