2017-12-22 20 views
3

작업 개체에 대한 정보를 저장하는 SQL Server 2012의 기본 테이블 (database0의 table0)이 있습니다. 각 작업은 고유 한 ID를 가지며 주 테이블에는 하나의 항목 (행) 만 있습니다. 작업 오브젝트에 대한 각각의 수정은 동일한 데이터베이스의 다른 테이블 (databese0의 table1)에서 새로운 행을 작성합니다. 얼마 후 에이전트는 table1 (데이터베이스 0)의 행을 다른 데이터베이스 (database1의 table2)에있는 다른 테이블로 이동합니다. 기본적으로 작업 테이블의 각 변경 사항을 감사 테이블에 로깅하고 에이전트가 감사 테이블에서 다른 데이터베이스의 다른 감사 테이블로 항목을 이동합니다. 이 같은 데이터를 반환MS SQL Server 2012의 다른 테이블에서 연속적인 행을 빼는 방법은 무엇입니까?

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 

나는 많은 시간이 각 상태에서 소비 된 각 작업을 얼마나 측정 할 필요가

나는 쿼리를했다. 그래서 기본적으로 각 작업에 대해 작업이 생성 된 순간부터 최종 상태 (완료/완료되지 않음) 중 하나가 될 때까지 적절한 타임 스탬프 연속 행 (동일한 테이블 또는 다른 테이블에서)을 빼고 결과를 적절한 행에 넣어야합니다. 에

예를 들어 작업 1은 12:00:00와 다음 StatusChange에 생성 된
  1. 은 상태 "대기"로 이동 : 작업 1에 대한

    Job_ID | New | Wait | InProg. | Total_Time | Final_Status 
    --------|-------|--------|-----------|------------|------------- 
        Job1 | 15 | 15 |  10 |  40  | Finished 
        Job2 | 15 | 0 |  5  |  20  | Unfinished 
    

    예 :이 같은 결과를 얻을 필요 12:10:00. 그래서 job1은 10 분 동안 "New"상태였습니다.

  2. 다음 StatusChange는 12:25:00에서 상태 "New"로 다시 변경되었습니다. 따라서 작업 1은 15 분 동안 "대기"상태입니다.
  3. 다음 StatusChange는 12:30:00에 상태 "InProgress"에있었습니다. 그러나이 엔트리는 다른 테이블 (t2)입니다. 그래서 작업 1은 "New"상태 ("10 분")에 대해 이전 측정에 추가되어야하는 5 분 (t2.TimeStamp - t1.TimeStamp) 동안 "New"상태로 다시 돌아 왔고 마지막으로 15 분을줍니다 상태 "새"합계.
  4. 마침내 마지막 StatusChange는 12시 40 분에 상태 "Finished"였습니다. 그래서 job1은 10 분 동안 "InProgress"상태에 있습니다.
  5. 또한 각 작업 상태에 대한 시간 합계 인 총 시간을 측정해야합니다.이 예제에서는 Job1의 경우 40 분입니다. 또한 Job1에 대해 "Finished"인 최종 상태를 작성해야합니다.

기존 테이블을 수정해서는 안됩니다.

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 
+1

샘플 데이터를 소모품 형식으로 게시 할 수 있습니까? 이것은'DDL'과'INSERT' 문을 게시하는 것을 의미합니다. 나는 대답을 가지고있다. 그러나 그것은 시험되지 않았다. 따라서 모든 구문 또는 논리적 오류는 테스트 할 수있을 때까지 수정할 수 없습니다. – Larnu

답변

0

하지만, 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; 
+0

@Lamu 테스트를 위해 SQL 코드로 질문을 업데이트했습니다. 그에 따라 코드를 수정할 수 있다면 좋을 것입니다. 테이블 t0과 t1은 하나의 데이터베이스에 있고 테이블 t2는 다른 데이터베이스에 있다는 것을 명심하십시오. 또한 최종 상태 변경 (예 : "완료 됨"상태의 작업) 후에 "StatusChange"와 다른 다른 변경 설명이있는 행이 더있을 수 있습니다. – InstantE