如何从MS SQL Server 2012中的不同表中减去连续的行?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从MS SQL Server 2012中的不同表中减去连续的行?相关的知识,希望对你有一定的参考价值。
我在SQL Server 2012中有一个主表(来自database0的table0),其中存储有关作业对象的信息。每个作业都有唯一的ID,主表中只有一个条目(行)。对作业对象的每个修改都在同一个数据库(来自databese0的table1)的不同表中创建一个新行。一段时间后,代理将行从table1(从database0)移动到另一个数据库中的另一个表(来自database1的table2)。基本上我将jobs对象上的每个更改记录到审计表中,并且在一段时间之后,代理将条目从审计表移动到不同数据库中的另一个审计表。
我提出了一个问题:
select t0.Job_ID,
t1.TimeStamp, t1.Status, t1.Change,
t2.TimeStamp, t2.Status, t2.Change
from [database0].dbo.[Table0] as t0
left outer join [database0].dbo.[Table1] as t1 on t1.Job_ID=t0.Job_ID
left outer join [database1].dbo.[Table2] as t2 on t2.Job_ID=t0.Job_ID
where t1.Status='Created' or t1.Change='StatusChange'
or t2.Status='Created' or t2.Change='StatusChange'
order by t0.Job_ID, t1.TimeStamp, t2.TimeStamp
哪个返回这样的数据:
t0.JobID|t1.TimeStamp|t2.TimeStamp|t1.Status|t2.Status|t1.Change|t2.Change
--------|------------|------------|---------|---------|---------|---------
Job1 |12:00:00.000| Null | New | Null | Created | Null
Job1 |12:10:00.000| Null | Wait | Null |St.Change| Null
Job1 |12:25:00.000| Null | New | Null |St.Change| Null
Job1 | Null |12:30:00.000| Null | InProgr.| Null |St.Change
Job1 | Null |12:40:00.000| Null | Finished| Null |St.Change
--------|------------|------------|---------|---------|---------|---------
Job2 |13:00:00.000| Null | New | Null | Created | Null
Job2 | Null |13:15:00.000| Null | InProgr.| Null |St.Change
Job2 | Null |13:20:00.000| Null |Unfinish.| Null |St.Change
我需要衡量每项工作在每种状态下花费的时间。所以基本上,对于每个作业,我需要从创建作业的那一刻开始减去TimeStamp连续行(来自相同或不同的表),直到最终状态之一(已完成/未完成)并将结果放入适当的行。我需要得到这样的结果:
Job_ID | New | Wait | InProg. | Total_Time | Final_Status
--------|-------|--------|-----------|------------|-------------
Job1 | 15 | 15 | 10 | 40 | Finished
Job2 | 15 | 0 | 5 | 20 | Unfinished
Job1的示例:
- 例如,Job1已在12:00:00创建,在下一个StatusChange上,它在12:10:00移至状态“等待”。因此,job1已经处于“新”状态10分钟。
- Next StatusChange在12:25:00再次处于“New”状态。因此,job1处于“等待”状态15分钟。
- Next StatusChange在12:30:00处于“InProgress”状态。但是这个条目是另一个表(t2)。所以job1再次处于“New”状态5分钟(t2.TimeStamp - t1.TimeStamp),需要将其添加到上一个状态为“New”(10分钟)的测量中,最后给我们15分钟状态为“新”。
- 最后,StatusChange在12:40:00处于“已完成”状态。因此,job1处于“InProgress”状态10分钟。
- 此外,我还需要测量总时间,即每个作业状态的总和时间,在本例中为Job1的时间为40分钟。我还需要为Job1写出“完成”的最终状态。
我不能修改现有的表。
可以使用SQL查询完成这样的事情,最有效的方法是什么?
提前致谢
用于测试的SQL代码:
创建表格:
USE [databasename0] -- replace databasename0 name
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[t0](
[Job_ID] [nvarchar](64) NULL,
[Attribute1] [nvarchar](64) NULL,
[Attribute2] [nvarchar](64) NULL,
)
GO
USE [databasename0] -- replace databasename0 name
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[t1](
[AuditTimeStamp] [datetime] NULL,
[Job_ID] [nvarchar](64) NULL,
[Status] [nvarchar](64) NULL,
[ChangeDescription] [nvarchar](64) NULL,
)
GO
USE [databasename1] -- replace databasename1 name with different database
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[t2](
[AuditTimeStamp] [datetime] NULL,
[Job_ID] [nvarchar](64) NULL,
[Status] [nvarchar](64) NULL,
[ChangeDescription] [nvarchar](64) NULL,
)
GO
插入:
INSERT INTO [database0].[dbo].[t0] -- replace database0 name
(Job_ID, Attribute1, Attribute2)
VALUES
('Job1','Test1','Test2'),
('Job2','Test3','Test4')
GO
INSERT INTO [database0].[dbo].[t1] --replace database0 name
(AuditTimeStamp,Job_ID,Status,ChangeDescription)
VALUES
('2017-12-21 12:00:00.000','Job1','New','Created'),
('2017-12-21 12:10:00.000','Job1','Wait','StatusChange'),
('2017-12-21 12:11:00.000','Job1','Wait','Other'),
('2017-12-21 12:25:00.000','Job1','New','StatusChange'),
('2017-12-21 12:26:00.000','Job1','New','Other'),
('2017-12-21 13:00:00.000','Job2','New','Created')
GO
INSERT INTO [database1].[dbo].[t2] -- replace database1 name
(AuditTimeStamp,Job_ID,Status,ChangeDescription)
VALUES
('2017-12-21 12:30:00.000','Job1','InProgress','StatusChange'),
('2017-12-21 12:31:00.000','Job1','InProgress','Other'),
('2017-12-21 12:40:00.000','Job1','Finished','StatusChange'),
('2017-12-21 13:15:00.000','Job2','InProgress','StatusChange'),
('2017-12-21 13:17:00.000','Job2','InProgress','Other'),
('2017-12-21 12:20:00.000','Job2','Unfinished','StatusChange')
GO
我希望它有错误,但我无法测试,因为OP尚未提供可消耗的样本数据。我很乐意在他们提供之后编辑这个答案(InstantE,一旦你这样做,请回复这个答案,以便我收到通知)。
WITH Leads AS (
SELECT T0.JobID,
ISNULL(T1.[TimeStamp], T2.[TimeStamp]) AS [TimeStamp],
LEAD(T1.[TimeStamp], T2.[TimeStamp]) OVER (PARTITION BY T0.JobId ORDER BY ISNULL(T1.[TimeStamp], T2.[TimeStamp]) ASc) AS NextTimeStamp,
ISNULL(T1.[Status], T2.[Status]) AS [Status],
LAST_VALUE(ISNULL(T1.[Status], T2.[Status])) OVER (PARTITION BY T0.JobID ORDER BY ISNULL(T1.[TimeStamp], T2.[TimeStamp])) AS FinalStatus
FROM YourTables --I haven't included your JOIN's and WHERE here, you'll need to replace that
)
SELECT JobID,
SUM(CASE [Status] WHEN 'New' THEN DATEDIFF(MINUTE, [TimeStamp], [NextTimeStamp]) END) AS New,
SUM(CASE [Status] WHEN 'Wait' THEN DATEDIFF(MINUTE, [TimeStamp], [NextTimeStamp]) END) AS Wait,
SUM(CASE [Status] WHEN 'InProgr.' THEN DATEDIFF(MINUTE, [TimeStamp], [NextTimeStamp]) END) AS [InProgr.],
SUM(DATEDIFF(MINUTE, [TimeStamp], [NextTimeStamp])) AS Total_time,
FinalStatus
FROM Leads
GROUP BY JobID, FinalStatus;
以上是关于如何从MS SQL Server 2012中的不同表中减去连续的行?的主要内容,如果未能解决你的问题,请参考以下文章
将数据从 MS Sql Server 存储过程导出到 excel 文件
按字母数字字符串 MS SQL Server 2012 中的相似性排序
将存储过程从 MS SQL Server 转换为 Informix
从 phpmyadmin 导出到 sql server 2012
在 Access 中使用 ODBC 连接到 MS SQL Server 2012:手动调用查询和在 VBA 中调用查询之间的巨大时间差异