2010-06-25 6 views
1

J'ai une table avec un journal d'audit:Running SQL Audit Log Totaux

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 

Je veux un total de fonctionnement de bogues ouverts et fermés comme:

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 

Comment puis-je faire cette requête (ou similaire) dans Microsoft SQL Server 2000? La sortie est destinée à être utilisée pour alimenter un graphique de série chronologique, donc je me fiche de savoir s'il y a des lignes avec 0 sortie car je ne sélectionnerai probablement qu'une période comme le mois dernier.

+0

Je pense que vous aurez besoin d'utiliser l'un des totaux de fonctionnement des solutions ici (peut-être un curseur) http://www.sqlteam.com/article/calculating-running -totaux. –

+0

La sortie désirée n'est PAS un histogramme (http://en.wikipedia.org/wiki/Histogram) et ne correspond PAS aux données d'échantillon fournies. –

+0

@Brock Adams: J'ai renommé 'Histogram' pour 'Running Total' afin de rendre plus facile de voir que la sortie désirée correspond aux données de l'échantillon – Eduardo

Répondre

2

Je pense que la sortie correspond effectivement à l'échantillon des données: le 25 (00 heures), il y a deux bugs ouverts. Le 26, il y a un bug ouvert et un fermé. Et le 27, tous les bugs sont fermés.

Il n'est pas clair comment les dates principales devraient être créées. Pour mon exemple, j'ai pré-chargé les dates que je savais être correctes mais cela pourrait être accompli de diverses manières en fonction des besoins de l'utilisateur.

Quoi qu'il en soit, le code est ci-dessous. Cela devrait fonctionner pour les cas où un bug est ouvert et fermé plusieurs fois le même jour. Il fonctionne sous l'hypothèse qu'un bug ne peut pas être ouvert et fermé en même temps.

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

Résultats:

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

Je suis arrivé avec la même solution plus tôt, mais j'ai alors réalisé que la sortie attendue semble être un total de bugs ouverts et de bugs fermés! –

+1

@ Martin Smith - suppose que j'aurais dû demander une clarification. Je pense que les totaux cumulés augmenteraient. L'exemple de sortie montre ouvert décroissant. En outre, l'exemple de sortie n'inclut pas le 24ème, donc j'ai pensé que l'exemple de sortie d'Eduardo n'était pas nécessairement fait pour correspondre aux données d'entrée. – MaasSql