Tentei pesquisar postagens, mas só encontrei soluções para o SQL Server / Access. Eu preciso de uma solução no MySQL (5.X).
Eu tenho uma tabela (chamada história) com 3 colunas: hostid, itemname, itemvalue.
Se eu fizer um select ( select * from history
), ele retornará
+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
| 1 | A | 10 |
+--------+----------+-----------+
| 1 | B | 3 |
+--------+----------+-----------+
| 2 | A | 9 |
+--------+----------+-----------+
| 2 | c | 40 |
+--------+----------+-----------+
Como faço para consultar o banco de dados para retornar algo como
+--------+------+-----+-----+
| hostid | A | B | C |
+--------+------+-----+-----+
| 1 | 10 | 3 | 0 |
+--------+------+-----+-----+
| 2 | 9 | 0 | 40 |
+--------+------+-----+-----+
Respostas:
Vou adicionar uma explicação um pouco mais longa e detalhada dos passos a serem tomados para resolver esse problema. Peço desculpas se for muito longo.
Começarei com a base que você forneceu e a utilizará para definir alguns termos que utilizarei para o restante deste post. Esta será a tabela base :
Este será o nosso objetivo, a bonita tabela dinâmica :
Os valores na
history.hostid
coluna se tornarão valores y na tabela dinâmica. Os valores nahistory.itemname
coluna se tornarão valores x (por razões óbvias).Quando tenho que resolver o problema de criar uma tabela dinâmica, resolvo-a usando um processo de três etapas (com uma quarta etapa opcional):
Vamos aplicar estas etapas ao seu problema e ver o que temos:
Etapa 1: selecione colunas de interesse . No resultado desejado,
hostid
fornece os valores de y eitemname
fornece os valores de x .Etapa 2: estenda a tabela base com colunas extras . Normalmente, precisamos de uma coluna por valor x. Lembre-se de que nossa coluna de valor x é
itemname
:Observe que não alteramos o número de linhas - apenas adicionamos colunas extras. Observe também o padrão de
NULL
s - uma linha comitemname = "A"
um valor não nulo para a nova colunaA
e valores nulos para as outras novas colunas.Etapa 3: agrupe e agregue a tabela estendida . Precisamos
group by hostid
, pois fornece os valores y:(Observe que agora temos uma linha por valor y). Ok, estamos quase lá! Nós só precisamos nos livrar daqueles feios
NULL
.Etapa 4: prettify . Vamos substituir todos os valores nulos por zeros, para que o conjunto de resultados seja melhor:
E pronto - nós construímos uma tabela dinâmica bonita e bonita usando o MySQL.
Considerações ao aplicar este procedimento:
itemvalue
neste exemploNULL
, mas também pode ser0
ou""
, dependendo da sua situação exatasum
, mascount
emax
também são usados frequentemente (max
é frequentemente utilizado na construção de uma linha "objetos" que tinham sido espalhados por várias linhas)group by
cláusula (e não se esqueçaselect
delas)Limitações conhecidas:
fonte
fonte
group by
.MAX
vez deSUM
porqueitemValue
são strings, não valores numéricos.Outra opção, especialmente útil se você tiver muitos itens que você precisa dinamizar, é permitir que o mysql construa a consulta para você:
FIDDLE Adicionado alguns valores extras para vê-lo funcionando
GROUP_CONCAT
tem um valor padrão de 1000, portanto, se você tiver uma consulta muito grande, altere esse parâmetro antes de executá-loTeste:
fonte
'ifnull(SUM(case when itemname = ''',
com''' then itemvalue end),0) AS
', `para'SUM(case when itemname = '''
com''' then itemvalue else 0 end) AS ',
. Isso gera termos comoSUM(case when itemname = 'A' then itemvalue else 0 end) AS 'A'
.Aproveitando a ideia de Matt Fenwick que me ajudou a resolver o problema (muito obrigado), vamos reduzi-lo para apenas uma consulta:
fonte
Eu edito a resposta de Agung Sagita da subconsulta para participar. Eu não tenho certeza sobre quanta diferença entre este caminho 2, mas apenas para outra referência.
fonte
usar subconsulta
mas será um problema se a subconsulta resultante mais de uma linha usar mais funções agregadas na subconsulta
fonte
Minha solução:
Produz os resultados esperados no caso enviado.
fonte
Eu faço isso para que
Group By hostId
ele mostre apenas a primeira linha com valores,como:
fonte
Eu descobri uma maneira de tornar meus relatórios convertendo linhas em colunas quase dinâmicos usando consultas simples. Você pode ver e testá-lo online aqui .
O número de colunas da consulta é fixo, mas os valores são dinâmicos e baseados nos valores das linhas. Você pode construí-lo. Então, eu uso uma consulta para criar o cabeçalho da tabela e outra para ver os valores:
Você pode resumir também:
Resultados do RexTester :
http://rextester.com/ZSWKS28923
Para um exemplo real de uso, este relatório mostra em colunas as horas de partida das chegadas de barco / ônibus com uma programação visual. Você verá uma coluna adicional não usada na última coluna sem confundir a visualização: ** sistema de venda de ingressos on-line e presencial
fonte
Se você pudesse usar o MariaDB, há uma solução muito, muito fácil.
Desde o MariaDB-10.02 , foi adicionado um novo mecanismo de armazenamento chamado CONNECT que pode nos ajudar a converter os resultados de outra consulta ou tabela em uma tabela dinâmica, exatamente como você deseja: Você pode conferir os documentos .
Antes de tudo, instale o mecanismo de armazenamento de conexão .
Agora, a coluna dinâmica de nossa tabela está
itemname
e os dados de cada item estão localizados naitemvalue
coluna, para que possamos ter a tabela dinâmica de resultados usando esta consulta:Agora podemos selecionar o que queremos entre
pivot_table
:Mais detalhes aqui
fonte
Esta não é a resposta exata que você está procurando, mas era uma solução que eu precisava no meu projeto e espero que isso ajude alguém. Isso listará 1 a n itens de linha separados por vírgulas. O Group_Concat torna isso possível no MySQL.
Este cemitério tem dois nomes comuns, portanto os nomes são listados em linhas diferentes conectadas por um único ID, mas dois IDs de nome e a consulta produz algo como este
CemeteryID Cemetery_Name Latitude
1 Appleton, Sulpher Springs 35.4276242832293
fonte
Lamento dizer isso e talvez eu não esteja resolvendo seu problema exatamente, mas o PostgreSQL é 10 anos mais antigo que o MySQL e é extremamente avançado em comparação com o MySQL e há muitas maneiras de conseguir isso facilmente. Instale o PostgreSQL e execute esta consulta
então voila! E aqui está uma extensa documentação: PostgreSQL: Documentation: 9.1: tablefunc ou esta consulta
então novamente voila! PostgreSQL: Documentação: 9.0: hstore
fonte