Итоги выполнения журнала аудита SQL - PullRequest
1 голос
/ 26 июня 2010

У меня есть таблица с журналом аудита:

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, поскольку я, вероятно, выберу только временной интервал, как в прошлом месяце.

Ответы [ 2 ]

2 голосов
/ 26 июня 2010

Я думаю, что выходные данные на самом деле совпадают с образцами данных: 25-го (12:00) есть две открытые ошибки.26-го есть одна открытая ошибка и одна закрытая.А к 27-му все ошибки закрыты.

Не ясно, как должны быть созданы основные даты.Для моего примера я предварительно загрузил даты, которые, как я знал, были правильными, но это может быть выполнено различными способами в зависимости от требований пользователя.

В любом случае, код ниже.Это должно работать в тех случаях, когда ошибка открывается и закрывается несколько раз в один и тот же день.Он работает в предположении, что ошибка не может быть открыта и закрыта одновременно.

/** 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 голосов
/ 26 июня 2010
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
...