2010-06-25 181 views
1

我一個表的審計日誌:SQL審覈日誌運行總計

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個輸出的行,因爲我可能只會選擇上個月的時間範圍。

+0

我認爲你需要在這裏(也許光標)http://www.sqlteam.com/article/calculating-running使用運行總計解決方案之一-totals。 – 2010-06-25 22:04:49

+0

所需輸出不是直方圖(http://en.wikipedia.org/wiki/Histogram),並且與提供的樣本數據不匹配。 – 2010-06-26 02:54:02

+0

@Brock Adams:我已將'Histogram'更名爲'Running Total',以便更容易地看到提供所需的輸出與示例數據 – Eduardo 2010-06-26 05:29:15

回答

2

我認爲實際上輸出樣本數據相符:在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 
 
Date       #  Status 
2010-06-24 00:00:00.000  2  open 
2010-06-25 00:00:00.000  1  closed 
2010-06-26 00:00:00.000  1  closed 
+1

我早先提出了相同的解決方案,但後來意識到預期的輸出似乎是一個開放的錯誤和被修正的錯誤的總數! – 2010-06-26 02:20:20

+1

@馬丁史密斯 - 假設我應該要求澄清。運行總數,我認爲會增加。示例輸出顯示開放式下降。另外,示例輸出不包括第24行,因此我認爲Eduardo的示例輸出不一定與輸入數據匹配。 – MaasSql 2010-06-26 02:50:59