AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 247411
Accepted
John K. N.
John K. N.
Asked: 2019-09-11 00:36:37 +0800 CST2019-09-11 00:36:37 +0800 CST 2019-09-11 00:36:37 +0800 CST

É possível PIVOT em uma instrução LIKE

  • 772

É possível agrupar por elementos (como em COLUMN LIKE='Value%') em uma PIVOTtabela? 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.

sql-server sql-server-2014
  • 2 2 respostas
  • 1295 Views

2 respostas

  • Voted
  1. Best Answer
    McNets
    2019-09-11T00:45:54+08:002019-09-11T00:45:54+08:00

    SOMA(CASO

    Para um número limitado de nomes, você pode usar uma solução SUM(CASE desta forma:

    SELECT 
        'Database status' as [DB Status],
        SUM(CASE WHEN Name LIKE 'Test%' THEN 1 ELSE 0 END) As Test,
        SUM(CASE WHEN Name LIKE 'Prod%' THEN 1 ELSE 0 END) AS Prod,
        SUM(CASE WHEN Name = 'Migrated' THEN 1 ELSE 0 END) AS Migrated,
        SUM(CASE WHEN Name = 'Offline' THEN 1 ELSE 0 END) AS Offline,
        SUM(CASE WHEN Name = 'Reserved' THEN 1 ELSE 0 END) AS Reserved
    FROM 
        [Status];
    

    PIVÔ

    Se houver uma extensa lista de nomes, mas apenas alguns deles devem ser reescritos, você pode manter a solução PIVOT:

    SELECT 'Database Status' AS [DB Status],
    [Test], [Prod], [Migrated], [Offline], [Reserved]
    FROM
    (
        SELECT 
            ID, 
            CASE
                WHEN Name LIKE 'Test%' THEN 'Test'
                WHEN Name LIKE 'Prod%' THEN 'Prod'
                ELSE Name
            END AS Name
        FROM 
            [Status]
    ) AS Source
    PIVOT
    (
        COUNT(ID) FOR Name IN ([Test], [Prod], [Migrated], [Offline], [Reserved])
    ) AS PivotTable;
    

    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:

    DECLARE @cols nvarchar(max);
    
    SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(CASE WHEN Name LIKE 'Test%' THEN 'Test'
                                                        WHEN Name LIKE 'Prod%' THEN 'Prod'
                                                        ELSE Name END)
                       FROM [Status]
                       FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
    
    DECLARE @cmd nvarchar(max);
    
    SET @cmd = 
    'SELECT ''Database Status'' AS [DB Status],' + @cols + ' FROM
        (SELECT 
            ID, 
            CASE
                WHEN Name LIKE ''Test%'' THEN ''Test''
                WHEN Name LIKE ''Prod%'' THEN ''Prod''
                ELSE Name
            END AS Name
        FROM 
            [Status]
    ) AS Source
    PIVOT
    (
        COUNT(ID) FOR Name IN (' + @cols + ')
    ) PVT'
    
    EXEC(@cmd);
    

    db<>fique aqui

    • 12
  2. Peter Vandivier
    2019-09-11T00:49:13+08:002019-09-11T00:49:13+08:00

    Acho importante separar estritamente as duas tarefas que você está tentando executar em uma etapa aqui.

    1. Classificação
    2. Transformação

    Para classificar os dados, meu instinto aqui é recomendar uma tabela de pesquisa para mapear rigorosamente os registros para uma classe pai. por exemplo

    CREATE TABLE StatusType (
      ID     INT         IDENTITY PRIMARY KEY,
      [Name] VARCHAR(10) NOT NULL UNIQUE
    );
    GO
    ALTER TABLE [Status] 
      ADD StatusTypeID INT NOT NULL 
        DEFAULT 1
        FOREIGN KEY REFERENCES StatusType (ID) ;
    

    ...onde o registro de semente em StatusType( ID=1 para o Status.StatusTypeIDpadrã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.

    select 'Database Status' AS [DB Status],
        [Test], [Prod], [Migrated], [Offline], [Reserved]
    from (
        select s.ID,
               st.Name as StatusTypeName
        from status s
        join statusType st on st.ID = s.StatusTypeID
    ) as Source
    pivot (
        count(ID) for StatusTypeName in ([Test],[Prod],[Migrated],[Offline],[Reserved],[Unknown])
    ) as pvt;
    

    dbfiddle completo

    • 8

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve