2014-06-11 4 views
0

SSRS 보고서 빌더 응용 프로그램을 사용하여 매월 기록 된 사고의 수를 추적하는 시스템에 대한 BI 보고서를 작성합니다.이번 달에 마감 된 이전 달의 날짜를 얻는 방법

아래 나 쿼리

Month  Logged Received Closed Remaining 
January 200  220  150  70 
February 150  220  200  20 
March  110  130  100  30 
April  200  230  200  30 

을 만들어야 테이블이며, 각 열은 다음과 같이 정의에서

기록 된 = 오픈 사고 오픈 예 당월 1/1/2014 년 1 월 1 일부터 3114 년 1 월 31 일까지 (현재 월 데이터 만 포함)

Received = 기록 된 사고 + 아직 열리지 않은 이전 달의 남은 잔여 누계 지난 달 남은 g ive me 총 220입니다. 현재 달에 개폐 이번 달에 +를

남은 =받은이 달에 폐쇄 전월 남아있다

청산 = 사건 -

내가 사용되는 코드

폐쇄

SELECT group_id, YEAR(Opendate) AS Year, MONTH(Opendate) AS Month, 
     COUNT(CASE WHEN Month(Closedate) = Month(Opendate) 
      AND Month(closedate)> Month (opendate) THEN 1 ELSE NULL END) AS closed, 
     COUNT(*) AS Logged, 
FROM Incidents 
WHERE (Opendate >= @YearStart) AND (Opendate <= @YearEnd) 
GROUP BY YEAR(Opendate), MONTH(Opendate), group_id 
ORDER BY Year, Month,group_id 
:

아래 현재 월에 폐쇄되었다 또한 단지 나에게주는 이전 달 동안 나에게 가까이 사건을 포기하지 않는 것은 내가 내 쿼리에 사용되는 코드입니다

로깅 된 상태가 정상적으로 작동합니다. 수신 및 남아 있습니다.


나는 Union를 사용하려하고 내가받은 데이터는 다음과 같습니다 로그온 및 폐쇄 데이터

Select count(*) logged,year(opendate) as year1,MONTH(opendate) as 
month1,'Logged' as status1 
From Incidents 
where opendate is not null 
GROUP BY year(opendate),MONTH(opendate) 
UNION 
Select count(*) closed,year(Closedate) as year1,MONTH(Closedate) as 
month1,'All_Closed' as status1 
From Incidents 
where Closedate is not null 
GROUP BY year(Closedate),MONTH(Closedate) 
UNION 
Select count(*) Remaining,year(opendate) as year1,MONTH(opendate) as 
month1,'Current_Month_Not_Closed' as status1 
From Incidents 
where Month(Closedate) > MONTH(Opendate) 
GROUP BY year(opendate),MONTH(opendate) 
UNION 
Select count(*) Month_Closed,year(opendate) as year1,MONTH(opendate) as 
month1,'Current_Month_Close' as status1 
From Incidents 
where MONTH(Closedate) = MONTH(Opendate) 
GROUP BY year(opendate),MONTH(opendate) 
order by year1,month1 

을 가지고 : 티켓의 수있을 것입니다 수신

logged | year1 | month1 | status1 
-------+-------+--------+------------------------- 
    1093 | 2014 |  1 | Logged 
    1089 | 2014 |  1 | All_Closed 
    997 | 2014 |  1 | Current_Month_Close 
    96 | 2014 |  1 | Current_Month_Not_Closed 
    1176 | 2014 |  2 | Logged 
    1176 | 2014 |  2 | All_Closed 
    91 | 2014 |  2 | Current_Month_Not_Closed 
    1085 | 2014 |  2 | Current_Month_Close 
    1340 | 2014 |  3 | Logged 
    1327 | 2014 |  3 | All_Closed 
    107 | 2014 |  3 | Current_Month_Not_Closed 
    1232 | 2014 |  3 | Current_Month_Close 
    116 | 2014 |  4 | Current_Month_Not_Closed 
    1320 | 2014 |  4 | Current_Month_Close 
    1424 | 2014 |  4 | All_Closed 
    1441 | 2014 |  4 | Logged 
    1167 | 2014 |  5 | Current_Month_Close 
    105 | 2014 |  5 | Current_Month_Not_Closed 
    1277 | 2014 |  5 | Logged 
    1283 | 2014 |  5 | All_Closed 
+0

날짜를 – Muneera

답변

0

신뢰할 수있는 데이터를 얻으려면 앵커가 사용할 수있는 달력 테이블이 있어야하며, 티켓이 시작일로부터 몇 달 동안 살아있을 수 있거나 티켓이 생성되지 않은 한 달이있을 수 있습니다. 일정 테이블 (또는 온도, 또는 CTE)없이 상기 가상 데이터

CREATE TABLE Incidents (
    id int identity(1, 1) 
, group_id nvarchar(100) 
, Opendate Datetime 
, Closedate Datetime 
) 

INSERT INTO Incidents 
VALUES ('Service Desk', '20140107', '20140120') 
    , ('Service Desk', '20140117', '20140123') 
    , ('Service Desk', '20140127', '20140313') 
    , ('Service Desk', '20140310', '') 
-- from an OP comment the open tickets have the Closedate '' (1900-01-01) 

예는 결과 집합에서 2011 년 2 월에 추가하는 방법은 세 번째 기록이 모두 "수신하더라도 없기 때문이다

","남은 시간 "으로 표시됩니다.

캘린더를 만들려면 여러 가지 방법이 있습니다.이 경우에는 몇 개월에 대한 정보가 필요하지만 일에 대한 정보는 필요하지 않으므로 생성되지 않습니다. 여기

declare @YearStart date = '20140101' 
declare @YearEnd date = '20140430' 

;WITH D(N) AS (
      SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 
UNION ALL SELECT 8 UNION ALL SELECT 9 
) 
SELECT EOM 
    = DATEADD(D, -1, DATEADD(M, u.N + 10 * t.N + 1 
      , DATEADD(Y, DATEDIFF(Y, 0, @YearStart), 0))) 
    , pMonth = u.N + 10 * t.N 
FROM D u 
     CROSS JOIN D t 
WHERE u.N + 10 * t.N <= DATEDIFF(M, @YearStart, @YearEnd) 

EOM 월말의 날짜입니다, 사건 월에 폐쇄하고 pMonth이 @YearStart부터 진보 월 있는지 확인하는 데 사용됩니다. 이 상수 날짜 9999-12-31, pOpenDatepClosedate을 사용하기위한

이제 우리는 항상 OpenDate보다 높은 값을 가지고

SELECT ID 
    , OpenDate 
    , Closedate = COALESCE(NULLIF(Closedate, ''), '99991231') 
    , pOpenDate = DATEDIFF(M, @YearStart, OpenDate) 
    , pClosedate = DATEDIFF(M, @YearStart 
        , COALESCE(NULLIF(Closedate, ''), '99991231')) 
FROM Incidents 

Closedate 필요 사용 입사 테이블의 데이터를 준비해야 이전에 pMonth으로, 각각 OpenDateClosedate의 @YearStart에서 시작하는 점진적인 달입니다. 그것은을 togheter 그 퍼팅

@YearStart@YearEnd과 살아있는 모든 사건 사이에 일정 테이블에서 달을 얻기 위해 JOIN를 사용하여 메인 쿼리

declare @YearStart date = '20140101' 
declare @YearEnd date = '20140430' 

;WITH D(N) AS (
      SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 
UNION ALL SELECT 8 UNION ALL SELECT 9 
), CM AS (
    SELECT EOM 
     = DATEADD(D, -1, DATEADD(M, u.N + 10 * t.N + 1 
       , DATEADD(Y, DATEDIFF(Y, 0, @YearStart), 0))) 
     , pMonth = u.N + 10 * t.N 
    FROM D u 
     CROSS JOIN D t 
    WHERE u.N + 10 * t.N <= DATEDIFF(M, @YearStart, @YearEnd) 
), I AS (
    SELECT ID 
     , OpenDate 
     , Closedate = COALESCE(NULLIF(Closedate, ''), '99991231') 
     , pOpenDate = DATEDIFF(M, @YearStart, OpenDate) 
     , pClosedate = DATEDIFF(M, @YearStart 
        , COALESCE(NULLIF(Closedate, ''), '99991231')) 
    FROM Incidents 
) 
SELECT MONTH(CM.EOM) [Month] 
    , Logged = SUM(CASE WHEN pOpenDate = pMonth 
         THEN 1 
         ELSE 0 
        END) 
    , Received = Count(i.id) 
    , Closed = SUM(CASE WHEN pClosedate = pMonth 
          AND i.Closedate < CM.EOM 
         THEN 1 
         ELSE 0 
        END) 
    , Remaining = SUM(CASE WHEN i.Closedate > CM.EOM 
          THEN 1 
          ELSE 0 
         END) 
FROM CM 
     INNER JOIN I ON CM.pMonth 
        BETWEEN i.pOpenDate AND i.pClosedate 
WHERE CM.EOM <= @YearEnd 
GROUP BY CM.EOM 
ORDER BY CM.EOM 

SQLFiddle Demo

을 만들 수 있어요 달. 이들의 속성은 CASE 로직으로 계산되며, 티켓이 살아있는 경우 Received 인 경우 논리가 필요하지 않으므로 수신됩니다.

CASEBIT 논리로 변환 할 수 있습니다 모든

declare @YearStart date = '20140101' 
declare @YearEnd date = '20140430' 

;WITH D(N) AS (
      SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 
UNION ALL SELECT 8 UNION ALL SELECT 9 
), CM AS (
    SELECT EOM 
     = DATEADD(D, -1, DATEADD(M, u.N + 10 * t.N + 1 
       , DATEADD(Y, DATEDIFF(Y, 0, @YearStart), 0))) 
     , pMonth = u.N + 10 * t.N 
    FROM D u 
     CROSS JOIN D t 
    WHERE u.N + 10 * t.N <= DATEDIFF(M, @YearStart, @YearEnd) 
), I AS (
    SELECT ID 
     , OpenDate 
     , Closedate = COALESCE(NULLIF(Closedate, ''), '99991231') 
     , pOpenDate = DATEDIFF(M, @YearStart, OpenDate) 
     , pClosedate = DATEDIFF(M, @YearStart 
        , COALESCE(NULLIF(Closedate, ''), '99991231')) 
    FROM Incidents 
) 
SELECT MONTH(CM.EOM) [Month] 
    , Logged = SUM(1 - CAST(pOpenDate - pMonth AS BIT)) 
    , Received = Count(i.id) 
    , Closed = SUM(1 - CAST(pClosedate - pMonth AS BIT)) 
    , Remaining = SUM(0 + CAST(i.pClosedate/(CM.pMonth + 1) AS BIT)) 
FROM CM 
     INNER JOIN I ON CM.pMonth 
       BETWEEN i.pOpenDate AND i.pClosedate 
WHERE CM.EOM <= @YearEnd 
GROUP BY CM.EOM 
ORDER BY CM.EOM; 

SQLFiddle Demo

비트 논리가 어떻게 CASTBIT에 작품에 기지 :

  • 0 이동 0에
  • 다른
  • 모든 (A 및 B 정수와) 그 기반으로 한

로 이동 : A = B

  • CAST(A/(B + 1) AS BIT) 인 경우

    • 1 - CAST(A - B AS BIT)이 1 인 1 A > B합니다 (0 +는 암시를 강제하는 것입니다 때 INT으로 전송 된 BITSUM med 일 수 없습니다.
  • +0

    위의 쿼리는 정확한 데이터를 모두에게, 로그, 닫힌, remainig,받은 적이 – Muneera

    +0

    받았습니다 정확히 '20140101 00:00:00'에서 ' 20140331 23:59:59 ' – Muneera

    +0

    폐쇄 된 기능은 달 또는 이전 달에 열려 있지만 같은 달에 개폐되는 것은 물론이 달에 휴무일뿐입니다. – Muneera

    0

    그 월말 이전에 문을 열었으며 월 초에 문을 닫지 않았습니다.

    count(case when OpenDate <= @EndOfMonth and 
           (@StartOfMonth >= CloseDate or CloseDate is null) then 1 end) 
        as Received 
    

    청산은 간단하다 :

    count(case when CloseDate between @StartOfMonth and @EndOfMonth 
           then 1 end) as Closed 
    

    당신은 구글을 ​​사용하여 한 달의 시작과 끝을 계산하는 방법을 알아낼 수 있어야합니다.

    +0

    내가 시도하고 당신을 업데이 트됩니다 – Muneera

    관련 문제