É possível agrupar por elementos (como em COLUMN LIKE='Value%'
) em uma PIVOT
tabela? Eu tenho uma tabela [DBT].[Status] que contém vários status (de bancos de dados, instâncias, etc.) e não quero dinamizar/consultar todos os valores PROD e TEST como valores únicos, mas agrupá-los.
Por exemplo, em vez de ter colunas para os status Prod
, Prod ACC
, Prod APP
, .. etc. eu teria apenas uma coluna contendo os valores para Name LIKE 'Prod%'
e Name LIKE 'Test%'
.
O que tenho até agora:
Definição de tabela
CREATE TABLE [DBT].[Status](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Status] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY],
CONSTRAINT [IX_Status] UNIQUE NONCLUSTERED
(
[Name] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
GO
Valores da tabela
INSERT INTO [DBT].[Status]
(
-- ID -- this column value is auto-generated
Name
)
VALUES
('Test ACC'),
('Test APP'),
('Test DBA'),
('Prod ACC'),
('Prod APP'),
('Prod DBA'),
('Prod'),
('Test'),
('Migrated'),
('Offline'),
('Reserved')
A Tabela de Status Dinâmica
SELECT 'Database Status' AS [DB Status],
[1] AS [Test ACC], [2] AS [Test APP], [3] AS [Test DBA], [4] AS [Prod ACC], [5] AS [Prod APP], [6] AS [Prod DBA], [7] AS [Prod], [8] AS [Test], [9] AS [Migrated], [10] AS [Offline], [11] AS [Reserved]
FROM
(
SELECT ID, Name FROM [DBT].[Status]
) AS Source
PIVOT
(
COUNT(Name) FOR ID IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11])
) AS PivotTable
Saída até agora
DB Status Test ACC Test APP Test DBA Prod ACC Prod APP Prod DBA Prod Test Migrated Offline Reserved
--------------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
Database Status 1 1 1 1 1 1 1 1 1 1 1
db<>violino
O dbfiddle até agora.
Pergunta
Em vez de ter várias linhas para os vários valores Test...
e Prod....
, prefiro agrupá-los, semelhante ao seguinte:
DB Status | Test | Prod | Migrated | Offline | Reserved
--------------- | ---- | ---- | -------- | ------- | --------
Database Status | 4 | 4 | 1 | 1 | 1
Não tenho a menor ideia de como resolver minha dúvida. (Para ser honesto, acabei de entender o PIVOT ontem, após extensas tentativas e erros).
Esta pergunta está vagamente relacionada à pergunta Como criar somas/contagens de itens agrupados em várias tabelas que já perguntei. As tabelas [DBT].[Instance] e [DBT].[Database] contêm uma coluna com o [StatusID] que corresponde à tabela que estamos vendo agora.
SOMA(CASO
Para um número limitado de nomes, você pode usar uma solução SUM(CASE desta forma:
PIVÔ
Se houver uma extensa lista de nomes, mas apenas alguns deles devem ser reescritos, você pode manter a solução PIVOT:
db<>fique aqui
CONSULTA DINÂMICA
Se você se sentir um pouco preguiçoso e não quiser escrever todos os nomes das colunas, você pode usar uma consulta dinâmica:
db<>fique aqui
Acho importante separar estritamente as duas tarefas que você está tentando executar em uma etapa aqui.
Para classificar os dados, meu instinto aqui é recomendar uma tabela de pesquisa para mapear rigorosamente os registros para uma classe pai. por exemplo
...onde o registro de semente em
StatusType
(ID
=1 para oStatus.StatusTypeID
padrão) é um registro de espaço reservado chamado "Desconhecido" ou similar.Quando os dados de pesquisa são propagados e os registros de base são atualizados com as chaves corretas, você pode girar para o conteúdo do seu coração.
dbfiddle completo