2017-04-04 212 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