2016-12-02 1 views
0

나는 다음과 같은 단순화 된 테이블이 : 어떻게 그룹 달과 날짜 시간 필드가 많은 서비스는 특히, 생성 된 허가 또는 폐쇄 된 방법을 계산 할 수SQL 쿼리에서 날짜의 발생을 찾기

Create table Services (
    ServiceID int  not null, 
    Created  Datetime null, 
    Authorised DateTime null, 
    Closed  Datetime null) 

을 달?

Month Year Created Authorised Closed 
08 2016  10   12   3 
09 2016  12   4   9 
10 2016  7   9   6 
... 
... 

나는 그것이 간단한데에도 불구하고,이를 달성하기 위해 GROUPBY 문을 알아낼 수 아니다 :

내가 찾고 있어요 결과입니다. 누구든지 도와 줄 수 있습니까?

답변

1

월별 생성 개수, 월별 인증 개수 및 월별 폐쇄 계수를 별도로 선택하고 완전히 외부 결합하십시오.

불행히도 SQL Server에는 표준 SQL의 JOIN table USING (columns)이 없으므로, 특히 두 개 이상의 테이블이 포함 된 완전 외부 조인은 어색합니다.

select 
    coalesce(closed.mon, created.mon, authorised.mon) as [Month], 
    coalesce(closed.yr, created.yr, authorised.yr) as [Year], 
    created.cnt as [Created], 
    created.cnt as [Authorised], 
    authorised.cnt as [Closed] 
from 
(
    select month(created) as mon, year(created) as yr, count(*) as cnt 
    from services 
    group by month(created), year(created) 
) created 
full outer join 
(
    select month(authorised) as mon, year(authorised) as yr, count(*) as cnt 
    from services 
    group by month(authorised), year(authorised) 
) authorised on authorised.mon = created.mon and authorised.yr = created.yr 
full outer join 
(
    select month(closed) as mon, year(closed) as yr, count(*) as cnt 
    from services 
    group by month(closed), year(closed) 
) closed on closed.mon = coalesce(created.mon, authorised.mon) 
     and closed.yr = coalesce(authorised.yr, created.yr); 
+0

와우. 그것은 소수입니다. 내 실제 테이블에 실제로 더 많은 날짜/시간 열이 있으므로 수정할 수 있는지 확인해야합니다. 8 개의 완전한 외부 조인을 만드는 것은 좋은 생각처럼 보이지 않습니다! – navigator

+0

너무 걱정하지 마십시오. DBMS는 이러한 일을 정확하게 수행하도록 만들어졌습니다. 여기에 해시 조인을 사용할 수 있습니다. 데이터가 이미 집계 되었기 때문에 조인 할 필요가있는 레코드가 거의 없다는 것을 기억하십시오. –

1
;WITH CTECR (Y, M) AS (
    SELECT 
     DATEPART(Year, Created), 
     DATEPART(Month, Created) 
    FROM [Services] 
), 
CTEA (Y, M) AS (
    SELECT 
     DATEPART(Year, Authorised), 
     DATEPART(Month, Authorised) 
    FROM [Services] 
), 
CTECL (Y, M) AS (
    SELECT 
     DATEPART(Year, Closed), 
     DATEPART(Month, Closed) 
    FROM [Services] 
) 
SELECT M, Y, ISNULL(Created, 0), ISNULL(Authorised, 0), ISNULL(Closed, 0) FROM (
SELECT M, Y, COUNT(*) AS 'Cnt', 'Created' AS 'Evt' FROM CTECR GROUP BY M, Y 
UNION ALL 
SELECT M, Y, COUNT(*), 'Authorised' FROM CTEA GROUP BY M, Y 
UNION ALL 
SELECT M, Y, COUNT(*), 'Closed' FROM CTECL GROUP BY M, Y 
) A 
PIVOT (
    SUM(Cnt) 
    FOR Evt IN (Created, Authorised, Closed) 
) AS PivotTable; 
+0

이것은 유망 해 보이지만 다른 그룹화 열과 함께 실제 테이블에 더 많은 날짜/시간 열이 있습니다. 나는 이것이 나를 위해 실행할 수 있는지보기 위해 노력할 것이다. 감사! – navigator

0

나는 그룹화 집합을 사용해보십시오. 샘플 데이터 -

declare @temp table (
    ServiceID  int   not null, 
    Created   Datetime null, 
    Authorised  DateTime null, 
    Closed   Datetime null 
) 

insert into @temp 
select 1, '2016-08-03', '2016-07-03', '2016-02-03' union 
select 2, '2016-10-03', '2016-04-03', '2016-08-03' union 
select 3, '2016-04-03', '2016-02-03', '2016-12-03' union 
select 4, '2016-04-03', '2016-01-03', '2016-10-03' 

실제 코드 -

;with grouped as (
select created  = format(created, 'yyyyMM'), 
     authorised = format(authorised, 'yyyyMM'), 
     closed  = format(closed, 'yyyyMM'), 
     count_val = count(*) 
from @temp 
group by grouping sets(
      format(created, 'yyyyMM'), 
      format(authorised, 'yyyyMM'), 
      format(closed, 'yyyyMM')) 
) 
,combined as(
select [Month]=right(created,2),[year]=left(created,4), created=count_val, authorised, closed 
from grouped 
where created is not null 
union all 
select [Month]=right(authorised,2),[year]=left(authorised,4), created, authorised=count_val, closed 
from grouped 
where authorised is not null 
union all 
select [Month]=right(closed,2),[year]=left(closed,4), created, authorised, closed=count_val 
from grouped 
where closed is not null 
) 
select [Month],[year],created=sum(created),authroised=sum(authorised),closed=sum(closed) 
from combined 
group by [Month],[year] 
관련 문제