【问题标题】:SQL Audit Log Running TotalsSQL 审计日志运行总计
【发布时间】:2011-03-08 11:33:17
【问题描述】:

我有一张带有审核日志的表:

BugId       Timestamp               Status
1           2010-06-24 10:00:00     open
2           2010-06-24 11:00:00     open
1           2010-06-25 12:00:00     closed
2           2010-06-26 13:00:00     closed

我想要打开和关闭的错误总数,例如:

Timestamp            #       Status
2010-06-25 00:00:00  2       open
2010-06-26 00:00:00  1       open
2010-06-26 00:00:00  1       closed
2010-06-27 00:00:00  2       closed

如何在 Microsoft SQL Server 2000 中执行此查询(或类似查询)?

输出旨在用于提供时间序列图表,因此我不在乎是否有输出为 0 的行,因为我可能只会选择像上个月这样的时间跨度。

【问题讨论】:

  • 我认为您需要在此处使用其中一种运行总计解决方案(可能是光标)sqlteam.com/article/calculating-running-totals
  • 所需的输出不是直方图 (en.wikipedia.org/wiki/Histogram) 并且与提供的示例数据不匹配。
  • @Brock Adams:我已将“直方图”重命名为“运行总计”,以便更轻松地查看提供的所需输出与样本数据匹配
  • 谢谢。现在很明显您想要运行总计,所需的输出可以与样本数据相匹配。
  • 您得到想要的答案了吗?如果是这样,你能接受吗?如果没有,你能澄清一下你还在寻找什么吗?通常,您提供的信息越多,就越有可能有人可以帮助您。

标签: sql sql-server sql-server-2000 audit cumulative-sum


【解决方案1】:

我认为输出实际上与示例数据匹配:在 25 日(上午 12 点),有两个未解决的错误。 26日,一开bug,一关。到 27 日,所有错误都已关闭。

不清楚应该如何创建主要日期。在我的示例中,我预先加载了我认为正确的日期,但这可以根据用户的要求以多种方式完成。

不管怎样,代码如下。这应该适用于在同一天多次打开和关闭错误的情况。它是在一个 bug 不能同时打开和关闭的假设下运行的。

/** Setup the tables **/
IF OBJECT_ID('tempdb..#bugs') IS NOT NULL DROP TABLE #bugs

CREATE TABLE #bugs (
  BugID INT,
  [Timestamp] DATETIME,
  [Status] VARCHAR(10)
) 

IF OBJECT_ID('tempdb..#dates') IS NOT NULL DROP TABLE #dates

CREATE TABLE #dates ( 
  [Date] DATETIME
) 

/** Load the sample data. **/
INSERT #bugs 
SELECT 1, '2010-06-24 10:00:00', 'open'   UNION ALL
SELECT 2, '2010-06-24 11:00:00', 'open'   UNION ALL
SELECT 1, '2010-06-25 12:00:00', 'closed' UNION ALL
SELECT 2, '2010-06-26 13:00:00', 'closed' 

/** Build an arbitrary date table **/
INSERT #dates 
SELECT '2010-06-24' UNION ALL  
SELECT '2010-06-25' UNION ALL  
SELECT '2010-06-26' UNION ALL  
SELECT '2010-06-27' 


/** 
Subquery x:
For each date in the #date table,
get the BugID and it's last status.
This is for BugIDs that have been
opened and closed on the same day.

Subquery y:
Drawing from subquery x, get the 
date, BugID, and Status of its
last status for that day

Main query:
For each date, get the count
of the most recent statuses for 
that date. This will give the
running totals of open and 
closed bugs for each date
**/
SELECT
  [Date],
  COUNT(*) AS [#],
  [Status]
FROM (
  SELECT 
    Date,
    x.BugID,
    b.[Status]
  FROM ( 
    SELECT
      [Date],
      BugID,
      MAX([Timestamp]) AS LastStatus
    FROM #dates d 
    INNER JOIN #bugs b 
    ON d.[Date] > b.[Timestamp]
    GROUP BY
      [Date],
      BugID
    ) x 
  INNER JOIN #bugs b
  ON x.BugID = b.BugID
  AND x.LastStatus = b.[Timestamp]
) y 
GROUP BY [Date], [Status]
ORDER BY [Date], CASE WHEN [Status] = 'Open' THEN 1 ELSE 2 END

结果:

Date                    #           Status
----------------------- ----------- ----------
2010-06-25 00:00:00.000 2           open
2010-06-26 00:00:00.000 1           open
2010-06-26 00:00:00.000 1           closed
2010-06-27 00:00:00.000 2           closed

【讨论】:

    【解决方案2】:
    use tempdb
    go
    create table audit_log
    (
    BugID integer not null
    , dt_entered_utc datetime not null  default ( getutcdate () )
    , [status] varchar(10) not null
    );
    
    
    INSERT INTO audit_log ( BugID, dt_entered_utc, [status] ) VALUES ( 1, '2010-06-24 10:00', 'open' );
    INSERT INTO audit_log ( BugID, dt_entered_utc, [status] ) VALUES ( 2, '2010-06-24 11:00', 'open' );
    INSERT INTO audit_log ( BugID, dt_entered_utc, [status] ) VALUES ( 1, '2010-06-25 12:00', 'closed' );
    INSERT INTO audit_log ( BugID, dt_entered_utc, [status] ) VALUES ( 2, '2010-06-26 13:00', 'closed' );
    
    SELECT
        [Date] = CAST ( CONVERT ( varchar, a.dt_entered_utc, 101 ) as datetime )
        , [#] = COUNT ( 1 )
        , [Status] =  a.status
    FROM audit_log a
    GROUP BY CAST ( CONVERT ( varchar, a.dt_entered_utc, 101 ) as datetime ), a.status
    ORDER by [Date] ASC
    
    日期 # 状态 2010-06-24 00:00:00.000 2 打开 2010-06-25 00:00:00.000 1 关闭 2010-06-26 00:00:00.000 1 关闭

    【讨论】:

    • 我早先提出了相同的解决方案,但后来意识到预期的输出似乎是打开的错误和关闭的错误的总和!
    • @Martin Smith - 假设我应该要求澄清一下。运行总数,我认为会增加。示例输出显示开路递减。此外,示例输出不包括 24 日,所以我认为 Eduardo 的示例输出不一定与输入数据匹配。
    猜你喜欢
    • 2018-04-26
    • 2018-01-25
    • 1970-01-01
    • 2012-08-31
    • 2011-10-24
    • 2020-05-04
    • 2020-04-13
    • 2011-08-05
    • 2010-10-11
    相关资源
    最近更新 更多