我有一张包含审核日志的表:
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 :(得分: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 :(得分: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