SQL Server:返回包含额外COUNT列的行中的结果

时间:2017-04-12 14:01:39

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

dbo.AllApps记录已运行的所有可执行文件,它有一个存储exe哈希值的列ApplicationHash,一个存储执行exe的UserID的列UserName

如果exe已运行10次,则表中将有10个条目具有相同的信息,但时间戳和执行该实例的用户不同。

我想生成一个报告,只返回10行中的1行(所有列的时间,名称,描述...)以及另外一列将提供exe的次数计数执行(在此示例中为10的总行数)以及执行exe的唯一用户数(在此示例中为3)。

有什么建议吗?

ApplicationHash TimeStamp UserName 
-----------------------------------
ABCDE12345      00:00:05  User1 
ABCDE12345      00:02:05  User2 
ABCDE12345      00:04:05  User1 
ABCDE12345      00:10:05  User3 
ABCDE12345      00:15:05  User3 
ABCDE12345      00:20:05  User1 
ABCDE12345      00:21:05  User2 
ABCDE12345      00:33:05  User2 
ABCDE12345      00:45:05  User1 
ABCDE12345      00:55:05  User1 

结果应该像这样:

ApplicationHash ProcessCount UserCount
--------------------------------------
ABCDE12345           10           3

以下是有人提出解决ProcessCount问题的问题,但我也需要一个唯一的用户名计数:

declare @StartDate datetime = '20170401';
declare @EndDate datetime   = '20170406';

select top 1 with ties
    ProcessCount = count(*) over (partition by ApplicationHash)
  , 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
  and ProductName = 'WizSvcUt Application'
order by row_number() over (partition by ApplicationHash order by ProcessStartTime desc)

1 个答案:

答案 0 :(得分:0)

您可以将count(distinct userName)添加到临时表中。我还将隐式联接更改为显式联接:

/* !!!!!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 and distinct user names*/
SELECT  ApplicationHash, 
        COUNT(ApplicationHash) AS ProcessCount, 
        COUNT(DISTINCT UserName) As UserCount
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
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
ORDER BY 
    ProcessStartTime DESC

我不确定2008版本是否支持此功能,但在2012年您只需使用over子句进行计数,并在单个查询中获得相同的结果:

SELECT 
    COUNT(*) OVER (PARTITION BY ApplicationHash) AS ProcessCount,
    COUNT(*) OVER (PARTITION BY ApplicationHash, UserName)  As UserCount
    ApplicationHash, 
    ProcessStartTime,
    ApplicationType,
    Description, 
    Publisher, 
    ProductName, 
    ProductVersion, 
    EventDescription, 
    CommandLine, 
    FileName
FROM dbo.AllApps
WHERE TokenType = 'Elevated'
AND ApplicationType != 'COM Class'
AND ApplicationType != 'ActiveX Control'
AND ProcessStartTime >= @StartDate
AND ProcessStartTime < @EndDate
ORDER BY 
    ProcessStartTime DESC