2016-07-04 2 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 

Используя сводную я могу получить обзор количества резервных копий для каждого дня недели:

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 для воскресенья: повторите попытку.

Как я огляделся, я обнаружил, что DYNAMIC PIVOT может быть ключом к решению этой головоломки. Другие предлагают 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 = Success и 2 = Failure right?

Вопрос, что происходит, когда резервная копия не запускается вообще в определенный день :)? как вы справляетесь с этой ситуацией, поскольку в этот день не будет записей. :)

/* 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 также присутствует в зависимости от хоста. Есть также больше, чем эти два результата, но это не должно быть слишком сложно продлить. Резервные копии, которые не запускались, действительно представляют собой другой вопрос и другой запрос. Пока я буду придерживаться суммы разных типов. Если сумма меньше, чем в другие дни, что-то пошло не так. – mokum

+0

Type_id представляет исходное программное обеспечение и тип резервного копирования. Type_id = 1, например, равен Acronis VMprotect, type_id = 2 равно двоичному назначению Acronis VMprotect, тип_id = 3 равен Symantec BackupExec и т. Д. – mokum

Смежные вопросы