2016-07-04 99 views
0

嗯,只有得到正确的标题花了我10分钟,我不确定我是否覆盖了我的问题。一些背景信息:我的表格包含来自多个服务器的备份结果。为简单起见某些行只是一个服务器:SQL Server:多列透视

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 

使用PIVOT我可以得到备份量为每个工作日的概述:

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 1 2 3 4 5 6 7 
-------------------------------------- 
SBS2011  2 2 2 2 2 3 2 

但是这个结果错过了一些关键信息。作为result_id等于“成功”和result_id等于“失败”,我想有结果看起来像这样:

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:1是星期日简写:成功,1:2等于星期日:失败。对于某些备份type_id,星期日可能会有1:3的列:retry。

当我环顾四周,我发现动态枢轴可能是解决这个难题的关键。其他人提出了PARTITION BY,但我还没有发现如何。 DYNAMIC PIVOT似乎是最有前途的,但我不知道如何。请帮我创建这个 - 对我来说很复杂 - 查询?

回答

0

如果你不想使用动态SQL摆弄你可以只保持它的静态和改变被枢接在列。

喜欢的查询:

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 

*/ 

查询:

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