2016-07-04 3 views
0

흠, 정확한 제목을 얻는 데 10 분이 걸렸으므로 내 질문을 다루는 것이 확실하지 않습니다. 일부 배경 정보 : 내 테이블에 여러 서버의 백업 결과가 포함되어 있습니다. 단순화를 위해 하나 개의 서버에 대한 일부 행 :SQL Server : 여러 열을 피벗

hostname 1 2 3 4 5 6 7 
-------------------------------------- 
SBS2011  2 2 2 2 2 3 2 

:에

select * from 
(
    select [hostname], [type_id], datepart(w, received) as workday from [backups] 
) TEMP 
pivot (
    count([type_id]) 
    for workday in 
    ([1], [2], [3], [4], [5], [6], [7]) 
) as pvt; 

결과 : 피벗을 사용하여

hostname type_id result_id received 
---------------------------------------- 
SBS2011  5  1  2016-06-28 
SBS2011  5  1  2016-06-28 
SBS2011  5  1  2016-06-29 
SBS2011  5  1  2016-06-29 
SBS2011  5  1  2016-06-30 
SBS2011  6  1  2016-06-30 
SBS2011  5  2  2016-07-01 
SBS2011  6  2  2016-07-01 
SBS2011  6  2  2016-07-01 
SBS2011  5  1  2016-07-02 
SBS2011  6  1  2016-07-02 
SBS2011  5  1  2016-07-03 
SBS2011  6  1  2016-07-03 
SBS2011  5  1  2016-07-04 
SBS2011  6  1  2016-07-04 

나는 주중에 대한 백업의 양에 대한 개요를 얻을 수 있습니다 그러나이 결과는 몇 가지 중요한 정보를 놓치게됩니다. result_id가 '성공'을 같고 result_id가 '실패'동등, I는 다음과 같이 할 수있는 결과를 가지고 싶다 :

hostname 1:1 1:2 2:1 2:2 3:1 3:2 4:1 4:2 5:1 5:2 6:1 6:2 7:1 7:2 
------------------------------------------------------------------- 
SBS2011  2 0 2 0 2 0 2 0 2 0 0 3 2 0 

곳 럼 이름 1 : 2 일요일과 같다 : 성공과 1 : 1 일요일에 속기 : 실패한. 일부 백업 type_id의 경우 sunday : retry에 대해 1 : 3 열이있을 수도 있습니다.

주위를 둘러 보았을 때, 동적 피봇 (DYNAMIC PIVOT)이이 퍼즐을 푸는 데 핵심이 될 수 있음을 발견했습니다. 다른 사람들은 PARTITION BY를 제안하지만, 아직 방법을 찾지 못했습니다. DYNAMIC PIVOT이 가장 유망한 것 같지만 어떻게 해야할지 모르겠습니다. 나에게 복잡한 검색어를 작성하도록 도와주세요.

답변

0

당신은 그냥 정적 유지에 피봇 열을 변경할 수 있습니다.

같은 쿼리

select * 
from 
(
    select 
     [hostname], 
     [type_id], 
     concat(datepart(w, received),':',result_id) as workday 
    from [backups] 
) TEMP 
pivot (
    count([type_id]) 
    for workday in (
     -- maybe you don't want the :3 option for all days? Adjust as needed 
     [1:1],[1:2],[1:3], 
     [2:1],[2:2],[2:3], 
     [3:1],[3:2],[3:3], 
     [4:1],[4:2],[4:3], 
     [5:1],[5:2],[5:3], 
     [6:1],[6:2],[6:3], 
     [7:1],[7:2],[7:3] 
    ) 
) as pvt; 

당신이 원하는 것과 유사한 결과를 줄 수 있는가?

0

이 내용을 확인하고 문제가 해결되는지 확인해보십시오 ...이 문제를 더욱 단순화 할 수 있지만 type_id (5 및 6)의 디코딩 내용을 알아야합니다. 더 많은 type_id가있을 것입니까?

result_id = 1 = 성공 = 2 = 실패가 맞습니까?

질문 특정 날짜에 백업이 전혀 실행되지 않으면 어떻게됩니까? :) 그 날의 기록이 없으므로 어떻게 그 상황을 처리합니까? :)

/* Create table and populate with sample data. 
create table Backups (hostname varchar(10), type_id int , result_id int , received datetime) 

insert into Backups (hostname , type_id ,result_id , received) values 
('SBS2011',  5 ,  1  ,'2016-06-28'), 
('SBS2011',  5 ,  1  ,'2016-06-28'), 
('SBS2011',  5 ,  1  ,'2016-06-29'), 
('SBS2011',  5 ,  1  ,'2016-06-29'), 
('SBS2011',  5 ,  1  ,'2016-06-30'), 
('SBS2011',  6 ,  1  ,'2016-06-30'), 
('SBS2011',  5 ,  2  ,'2016-07-01'), 
('SBS2011',  6 ,  2  ,'2016-07-01'), 
('SBS2011',  6 ,  2  ,'2016-07-01'), 
('SBS2011',  5 ,  1  ,'2016-07-02'), 
('SBS2011',  6 ,  1  ,'2016-07-02'), 
('SBS2011',  5 ,  1  ,'2016-07-03'), 
('SBS2011',  6 ,  1  ,'2016-07-03'), 
('SBS2011',  5 ,  1  ,'2016-07-04'), 
('SBS2011',  6 ,  1  ,'2016-07-04') 

select * , DatePart(w, received) from dbo.Backups b 

*/ 

쿼리 : 동적 SQL 바이올린하지 않으려면

SELECT -- S.*, F.* 
     S.[hostname], 
     S.[1] as [1:1], 
     F.[1] as [1:2], 
     S.[2] as [2:1], 
     F.[2] as [2:2], 
     S.[3] as [3:1], 
     F.[3] as [3:2], 
     S.[4] as [4:1], 
     F.[4] as [4:2], 
     S.[5] as [5:1], 
     F.[5] as [5:2], 
     S.[6] as [6:1], 
     F.[6] as [6:2], 
     S.[7] as [7:1], 
     F.[7] as [7:2] 

FROM 
(
    select * from 
    (
     select [hostname], [type_id], datepart(w, received) as workday , result_id as res_type from [backups] where result_id = 1 

    ) TEMP 
    pivot 
    (
     count([type_id]) 
     for workday in 
     ([1], [2], [3], [4], [5], [6], [7]) 
    ) as pvt 

) S 
LEFT OUTER JOIN 
(
    select * from 
    (
     select [hostname], [type_id], datepart(w, received) as workday , result_id as res_type from [backups] where result_id = 2 

    ) TEMP 
    pivot 
    (
     count([type_id]) 
     for workday in 
     ([1], [2], [3], [4], [5], [6], [7]) 
    ) as pvt 

) F ON S.res_type = F.res_type - 1 
WHERE F.hostname IS NOT NULL 
+0

예, 호스트에 따라 type_id의 1 - 4도 있습니다. 이 두 result_id가 더 많지만 확장하기가 너무 어렵지 않아야합니다. 실행에 실패한 백업은 실제로 또 다른 질문이며 또 다른 쿼리입니다. 지금은 다른 type_id의 합을 고수 할 것입니다. 합계가 다른 일보다 작 으면 무언가 잘못되었습니다. – mokum

+0

Type_id는 소스 소프트웨어 및 백업 유형을 나타냅니다. Type_id = 1은 예를 들어 Acronis VMprotect와 같고 type_id = 2는 Acronis VMprotect 이중 대상과 같고 type_id는 3과 같습니다. Symantec BackupExec 등 – mokum