SQL - 仅返回匹配的第一行

时间:2017-04-04 17:33:16

标签: sql sql-server sql-server-2008


dbo.AllApps记录所有已运行的可执行文件,它具有一个名为ApplicationHash的列,用于存储exe哈希值。
因此,如果exe已运行10次,则表中将有10个条目具有相同的信息但时间戳不同。
我想生成一个报告,它只返回10行中的一行(所有列的时间,名称,描述...)和一个附加列,它将提供exe执行次数的计数。
有什么建议吗?

`/* !!!!!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`

2 个答案:

答案 0 :(得分: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以找出原因。

答案 1 :(得分:0)

使用row_number()count(*) over()一起获取1,的{​​{1}}和{{3}}行。

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

更新:在不知道有关此表的数据类型和行的唯一ID的更多信息的情况下,我添加了ProcessCount表达式,以便在{{1}时将where包含在分区中}} = case,否则为常量(ProcessStartTime)。

ApplicationHash