我有一些数据,如:
BUG DATE STATUS
---- ---------------------- --------
9012 18/03/2008 9:08:44 AM OPEN
9012 18/03/2008 9:10:03 AM OPEN
9012 28/03/2008 4:55:03 PM RESOLVED
9012 28/03/2008 5:25:00 PM CLOSED
9013 18/03/2008 9:12:59 AM OPEN
9013 18/03/2008 9:15:06 AM RESOLVED
9013 18/03/2008 9:16:44 AM CLOSED
9014 18/03/2008 9:17:54 AM OPEN
9014 18/03/2008 9:18:31 AM RESOLVED
9014 18/03/2008 9:19:30 AM CLOSED
9015 18/03/2008 9:22:40 AM OPEN
9015 18/03/2008 9:23:03 AM RESOLVED
9015 19/03/2008 12:27:08 PM CLOSED
9016 18/03/2008 9:24:20 AM OPEN
9016 18/03/2008 9:24:35 AM RESOLVED
9016 19/03/2008 12:28:14 PM CLOSED
9017 18/03/2008 9:25:47 AM OPEN
9017 18/03/2008 9:26:02 AM RESOLVED
9017 19/03/2008 12:30:30 PM CLOSED
我想将其变成这样的东西:
DATE OPEN RESOLVED CLOSED
---------------------- -------- -------- --------
18/03/2008 9:08:44 AM 1 0 0
18/03/2008 9:12:59 AM 2 0 0
18/03/2008 9:15:06 AM 1 1 0
18/03/2008 9:16:44 AM 1 0 1
18/03/2008 9:17:54 AM 2 0 1
18/03/2008 9:18:31 AM 1 1 0
18/03/2008 9:19:30 AM 1 0 2
18/03/2008 9:22:40 AM 2 0 2
18/03/2008 9:23:03 AM 1 1 2
18/03/2008 9:24:20 AM 2 1 2
18/03/2008 9:24:35 AM 1 2 2
18/03/2008 9:25:47 AM 2 2 2
18/03/2008 9:26:02 AM 1 3 2
19/03/2008 12:27:08 PM 1 2 3
19/03/2008 12:28:14 PM 1 1 4
19/03/2008 12:30:30 PM 1 0 5
28/03/2008 4:55:03 PM 0 1 5
28/03/2008 5:25:00 PM 0 0 6
即。保持每个状态的错误运行计数。
这很容易使用游标进行编码,但我想知道你们中的任何一位SQL专家是否可以帮助查询来实现这一目标?
理想情况下mysql
,但我很想看到任何可行的内容。
答案 0 :(得分:2)
With T as
(
Select B.BugDate As MainDate, C.BugID, C.BugDate ,C.Status,row_number() over(partition by B.BugDate,C.BugID order by C.BugDate Desc) As RowNum From Bug B Cross Join Bug C where B.BugDate >= C.BugDate Group By B.BugDate,C.BugID,C.BugDate, C.Status
)
Select T.MainDate ,SUM(CASE WHEN T.Status = 'OPEN' THEN 1 ELSE 0 END) As SUM_OPEN,SUM(CASE WHEN T.Status = 'RESOLVED' THEN 1 ELSE 0 END) As SUM_RESOLVED
,SUM(CASE WHEN T.Status = 'CLOSED' THEN 1 ELSE 0 END) As SUM_CLOSED
From T
where T.RowNum = 1
Group By T.MainDate
Order By T.MainDate
答案 1 :(得分:1)
我自发的方法不会在SQL中,因为它需要一些循环来知道给定下一行时间的每个类别的状态。相反,我将获取原始数据并循环通过,根据每行的STATUS字段修改每个类别的数量,然后输出。如果你想要一个例子,比如说php,我可以给你一个。
另一种方法是将这些数据缓存在一个单独的表中,并在有新操作时更新它。这样你就可以更快地获取它。
答案 2 :(得分:1)
正如您所说的,您希望在任何SQL实现中得到答案,因此我正在为SQL Server 2005及更高版本提供答案,因为我正在使用Windows函数(Row_Number)和CROSS APPLY功能。
想法是获取给定时间的错误的最后状态。
解决方案:
Select BugDate,
SUM(Case When RowNum = 1 AND Status = 'OPEN' Then 1 Else 0 End) As Opened,
SUM(Case When RowNum = 1 AND Status = 'RESOLVED' Then 1 Else 0 End) As Resolved,
SUM(Case When RowNum = 1 AND Status = 'CLOSED' Then 1 Else 0 End) As Closed
FROM
(
Select B1.BugDate,T2.BugId,T2.RowNum,T2.[Status]
from Bug B1
CROSS APPLY
(
SELECT T1.BugDate,T1.BugId, B.[Status],
ROW_NUMBER() Over(Partition by B1.BugDate, T1.BugId Order By Case when B.[Status] IS NULL THEN 1000 ELSE 1 END,T1.BugDate Desc) AS RowNum
FROM
(
Select BugDate,BugId
FROM
(
Select Distinct BugDate
from Bug
) D
CROSS JOIN
(
Select Distinct BugId
FROm Bug
) AS I
)T1
LEFT OUTER JOIN BUG B ON T1.BugDate = B.BugDate and T1.BugId = B.BugId
WHERE T1.BugDate <= B1.BugDate --AND T1.BugId = B1.BugId
) T2
)T1
GROUP BY BugDate
Order By BugDate
我创建了一个与示例问题中提供的数据集相同的数据集,我得到的结果是:
Date Op Re Cl
2008-03-18 09:08:44.000 1 0 0
2008-03-18 09:10:03.000 1 0 0
2008-03-18 09:12:59.000 2 0 0
2008-03-18 09:15:06.000 1 1 0
2008-03-18 09:16:44.000 1 0 1
2008-03-18 09:17:54.000 2 0 1
2008-03-18 09:18:31.000 1 1 1
2008-03-18 09:19:30.000 1 0 2
2008-03-18 09:22:40.000 2 0 2
2008-03-18 09:23:03.000 1 1 2
2008-03-18 09:24:20.000 2 1 2
2008-03-18 09:24:35.000 1 2 2
2008-03-18 09:25:47.000 2 2 2
2008-03-18 09:26:02.000 1 3 2
2008-03-19 12:27:08.000 1 2 3
2008-03-19 12:28:14.000 1 1 4
2008-03-19 12:30:30.000 1 0 5
2008-03-28 16:55:03.000 0 1 5
2008-03-28 17:25:00.000 0 0 6
注意:您在结果集中缺少第2行,并且日期为18/03/2008 9:18:31 AM的行在结果中也不正确。
答案 3 :(得分:0)
子查询可以使用,但是它只有三种状态吗?它们是硬编码还是变化
修改
select <TableName>.DATE, (SELECT BUGS FROM CountTable WHERE DATE = <TableName>.DATE AND Status = 'OPEN') as 'OPEN'
, (SELECT BUGS FROM CountTable WHERE DATE = <TableName>.DATE ANDStatus = 'CLOSED') as 'CLOSED'
, (SELECT BUGS FROM CountTable WHERE DATE = <TableName>.DATE ANDStatus = 'RESOLVED') as 'RESOLVED'
FROM
<TableName>,
( SELECT DATE, STATUS, COUNT(BUG) as BUGS
FROM <TableName>
GROUP BY DATE,STATUS) as CountTable
WHERE CountTable.DATE = <TableName>.DATE
或者,对于更简单的解决方案
SELECT DATE, (SELECT count(BUGS) FROM <TableName> bugs2 WHERE Status = 'OPEN' AND bugs.DATE = bugs2.DATE) as 'OPEN'
, (SELECT count(BUGS) FROM <TableName> bugs2 WHERE Status = 'CLOSED' AND bugs.DATE = bugs2.DATE) as 'CLOSED'
, (SELECT count(BUGS) FROM <TableName> bugs2 WHERE Status = 'RESOLVED' AND bugs.DATE = bugs2.DATE) as 'RESOLVED'
FROM <TableName> bugs
group by DATE