3
respostas

Consulta de acordo com a hierarquia

Tenho uma seguinte tabela no SQL Server:

tabela com 4 campos e 9 linhas

Preciso de uma ajuda para um Select que organize a consulta de acordo com a hierarquia. O campo "Agrupamento" mostra o superior 1 nível menor que o serviço, não estou conseguindo organizar a hierarquia que procure o serviço que é 4, em seguida buscar seu superior no agrupamento que é nível 3 colocar na linha abaixo. Exemplo, todos que são do agrupamento de "Soluções 3" fiquem abaixo.

Abaixo mostra como ficaria segundo essa ordem:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

3 respostas

Deve existir jeitos mais inteligentes, mas de bate pronto foi o que me veio a mente. Funciona basicamente usando uma CTE recursiva para ir concatenando o caminho baseado na hierarquia, para no fim, conseguir dar um order by.

declare @exemplo table (agrupamento varchar(100), servico varchar(100), tipo_servico varchar(100), nivel smallint)

insert into @exemplo values
    ('Ouvidoria', 'Ouvidoria', 'Consolidador', 0),
    ('Ouvidoria', 'Central de Apoio', 'Consolidador', 1),
    ('Central de Apoio', 'Acessoria', 'Atendimento', 2),
    ('Central de Apoio', 'Soluções', 'Atendimento', 2),
    ('Central de Apoio', 'Soluções 3', 'Consolidador', 2),
    ('Central de Apoio', 'SAC', 'Atendimento', 2),
    ('Soluções 3', 'Monitoramento', 'Atendimento', 3),
    ('Soluções 3', 'SBPrev', 'Consolidador', 3),
    ('SBPrev', 'Listas', 'Atendimento', 4)

;WITH cte (identificador, agrupamento, servico, tipo_servico, nivel)
AS
(
    select 
        grupo_servico.servico as identificador, 
        grupo_servico.* 
    from 
        @exemplo grupo_servico
    where
        grupo_servico.nivel = 0

    UNION ALL

    select
         CAST(CONCAT(cte.identificador, grupo_servico.servico) as varchar(100)) as identificador
        , grupo_servico.* 
    from 
        @exemplo grupo_servico
        inner join cte on grupo_servico.nivel = cte.nivel + 1 and grupo_servico.agrupamento = cte.servico
)
SELECT
    agrupamento,
    servico,
    tipo_servico,
    nivel
FROM   
    cte
order by
    cte.nivel, cte.identificador

Não Funcionou, chegando em uma hierarquia de nível 5, o serviço fica muito separado do agrupamento, abaixo tem um exemplo de como fica:

Linha | Agrupamento                |  Serviço                                |Tipo de Serviço  | Nível |
    19  | Central e Suporte          | Mesa de Investimento      |Consolidador     |     3    |
    .
    .
    .
    31  | Mesa de Investimento  | Mesa de Investimento 1   | Atendimento     |    4    |
    32  | Mesa de Investimento  |Mesa de Investimento  2   | Atendimento     |    4    |
    33  | Mesa de Investimento  |Mesa de Investimento 3    | Atendimento     |    4    |

O exemplo anterior ele considera todos os níveis 3 antes do agrupamento, o que procura seria mais ou menos como abaixo

Linha | Agrupamento                |  Serviço                                 |Tipo de Serviço    | Nível |
    19  | Central e Suporte          | Mesa de Investimento       |Consolidador       |    3     |
    20  | Mesa de Investimento  | Mesa de Investimento 1    | Atendimento      |    4     |
    21  | Mesa de Investimento  | Mesa de Investimento  2   | Atendimento      |    4     |
    22  | Mesa de Investimento  | Mesa de Investimento 3    | Atendimento      |    4     |
    23  | Outro Agrupamento     |Serviço x                                | Consolidador      |    3     |

Acho que eu entendi o que você quer. Não necessariamente você quer ordenar primeiro pelo nível, mas sim que eles sigam a hierarquia.

Seria basicamente trocar o Order By da minha consulta acima.

order by
    cte.nivel, cte.identificador

Viraria:

order by
    cte.identificador

Se foi o que eu entendi, seria isso. Se eu entendi errado, você pode preencher a tabela temporária ali com dados que você precisa e mostrar o resultado do que a consulta retornou e comparar com o que você queria? Porque talvez eu possa estar confundido o que você precisa.

Abraços!