Desagrupar uma coluna no MYSQL

MySQL

30/05/2015

Gente estou com um problema e não achei resposta tenho uma consulta no MYSQL fiz select com duas tabelas e estão agrupadas por uma chave primaria eu quero desagrupar apenas um campo desta tabela que no caso são as datas de vencimento das parcelas.
Alguem pode me ajudar.
Márcio

Márcio

Curtidas 0

Melhor post

Marisiana Battistella

Marisiana Battistella

30/05/2015

Você pode postar o código?
Ficaria mais fácil entender e também poder te ajudar...
GOSTEI 2

Mais Respostas

Márcio

Márcio

30/05/2015

O codigo é o seguinte:

$sql = "SELECT *, MAX(paciente.num_parcelas)-SUM(financeira.parcelas_pg) AS 'parcelas_rest',
SUM(financeira.parcelas_pg) AS 'parcelas_pg1',
GROUP_CONCAT(venc_parcelas) AS 'venc_parc02'
FROM paciente inner join financeira on paciente.id = financeira.id_pac
where status=1
GROUP BY paciente.id
ORDER BY nome_pac ASC ";

No lugar de GROUP_CONCAT teria outro comando para poder exibir todos os "venc_parcelas" que está na tabela financeira pois está agrupado pelo GROUP BY e quero desagrupar só o "venc_parcelas".
A contatenação não satifaz o objetivo do sistema é possivél depois de agrupado desagrupar apenas esta a culuna "venc_parcelas" pois ela varia conforme o numero de parcelas porem ela é relacionada com o id da tabela paciente.
As tabelas "paciente e financeira" estão ligadas ao id e id_pac
GOSTEI 1
Marisiana Battistella

Marisiana Battistella

30/05/2015

Entendi, mas o teu SQL precisa ser melhorado e eu acho que você não precisa desse GROUP_CONCAT.
Não utilize SELECT * informe os nomes dos campos que você precisa que o SQL retorne.
E o agrupamento não vai funcionar justamente porque você está agrupando pelo ID que é um valor único para cada registro.

Você pode postar a estrutura dessas duas tabelas (nomes dos campos, FK e PK ) ?
GOSTEI 0
Márcio

Márcio

30/05/2015

[img:descricao=TB financeira]http://arquivo.devmedia.com.br/forum/imagem/433925-20150531-001517.png[/img]

[img:descricao=TB paciente]http://arquivo.devmedia.com.br/forum/imagem/433925-20150531-001543.png[/img]
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

30/05/2015

Você precisa listar as parcelas pagas e as parcelas restantes por data de vencimento das parcelas?

Veja se esse código se aproxima do que você precisa:
SELECT  fin.venc_parcelas AS 'venc_parc02',
       MAX(pac.num_parcelas) - SUM(fin.parcelas_pg) AS 'parcelas_rest',
       SUM(fin.parcelas_pg) AS 'parcelas_pg1'      
FROM paciente pac
INNER JOIN financeira fin
ON fin.id_pac = pac.id 
WHERE pac.status=1 
GROUP BY fin.venc_parcelas
ORDER BY pac.nome_pac ASC 
GOSTEI 0
Márcio

Márcio

30/05/2015

Se agrupar pelo venc_parcelas hora de exibir também aperceu o nome varias vezes testei este codigo preciso que apareça o nome uma vez e repita apenas as datas de cada paciente que está interligados ao id e id_pac com o concat deu um resultado quase bom pois quando exibe os dados ele concatena as datas de vencimentos não tem uma função de desagregação que possa ser usado com MAX ou MIN que possa desagregar apenas o campo esperado.
[img]http://arquivo.devmedia.com.br/forum/imagem/433925-20150531-145852.png[/img]

Esta é a imagem resultante do select. Preciso que em cada paciente mostre o campo venc_parcelas para determinado paciente mas mostre seu nome apenas uma vez.
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

30/05/2015

Nesse caso você precisa incluir o nome do paciente no retorno e no GROUP BY.
Na aplicação você terá que tratar a visualização dos dados...
SELECT pac.nome_pac,
       fin.venc_parcelas AS 'venc_parc02',
       MAX(pac.num_parcelas) - SUM(fin.parcelas_pg) AS 'parcelas_rest',
       SUM(fin.parcelas_pg) AS 'parcelas_pg1'      
FROM paciente pac
INNER JOIN financeira fin
ON fin.id_pac = pac.id 
WHERE pac.status=1 
GROUP BY pac.nome_pac,
         fin.venc_parcelas
ORDER BY pac.nome_pac ASC 
GOSTEI 1
Marisiana Battistella

Marisiana Battistella

30/05/2015

Outro ponto a ser analisado: Os valores que o SELECT retorna estão corretos? Você chegou a fazer essa conferência?
GOSTEI 0
Márcio

Márcio

30/05/2015

Sim o restante está funcional e atende o unico problema é a questão de as datas de venc estão sendo agrupadas de forma que não atende vou testar o codigo que vc implementou mas desde já agradeço a disponibilidade.
GOSTEI 0
Márcio

Márcio

30/05/2015

Mas o erro persiste ao executar o select todas as insindencias se repetem não consigo isolar a venc_parcelas vou tentar mudar a estrutura do BD financeira com campos dos pag para receber apenas um id_pac ou pensar outra coisa Mas agradeço.
GOSTEI 0
Marcos P

Marcos P

30/05/2015

Fica mais fácil para nós ajudarmos, se você criar a estrutura no Fiddle e colocar alguns registros para simularmos sua pesquisa !
GOSTEI 0
Márcio

Márcio

30/05/2015

Coloquei http://sqlfiddle.com/#!9/6a148/4
Gente do jeito que está no representado é o que eu preciso.
Só quero substituir o GROUP_CONCAT mas nada o restante tá ok ainda falta tratar as casas decimais para valores mas isso é o de menos só preciso de uma forma de substituir o concat mas nada.
Eu não consegui uma função de "desagregação" quando faço a substituição do group by os nomes também são exibidos na real preciso que o nome apareça uma vez e as datas de venc que estão ligadas ao tal nome apareça em sua totalidade..
Na exibição dá o resultado que preciso porem preciso substiuir o concat.
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

30/05/2015

Essa exibição dos dados é em um relatório?
Que ferramenta você está utilizando e qual é a linguagem de desenvolvimento?
GOSTEI 0
Márcio

Márcio

30/05/2015

Este select vai gerar relatório sim mas o sistema é mais complexo a linguagem é PHP pois está rodando na web.
Mas a ferramenta tem hora que netbeens mas agora estou no dreamweaver para facilitar o uso de tabelas e formulários.
GOSTEI 0
Marcos P

Marcos P

30/05/2015

Mas a ferramenta tem hora que netbeens mas agora estou no dreamweaver para facilitar o uso de tabelas e formulários.


Não entendi essa frase !

Como contingência, você não consegue pegar os dados como está gerando agora e desmembrando-os do lado da aplicação ?

Em relação a query que você colocou no Fiddle, qual sua necessidade ?

Manter as totalizações (parcelas_rest e parcelas_pg1 ) e individualizar os vencimentos (venc_parc02)...

nome_pac        parcelas_rest   parcelas_pg1     venc_parc02
--------------- --------------- --------------- ---------------
Carlos Barão         3              0              2015-06-21
Carlos Barão         3              0              2015-08-21
Carlos Barão         3              0              2015-07-21
Márcio André         5              0              2015-07-30
Márcio André         5              0              2015-09-30
Márcio André         5              0              2015-06-30
Márcio André         5              0              2015-08-30
Márcio André         5              0              2015-10-30

É isso ?
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

30/05/2015

Se o retorno dos dados está correto, o problema não é o SQL, o que falta é programar na aplicação para fazer a visualização desses dados.
GOSTEI 0
Márcio

Márcio

30/05/2015

Olha preciso que apareça : Aquele resultado sem o group concat só isso.
Na aplicação não é possível pois estou restringindo na sql e é preciso restringir é preciso uma solução ou na query ou mudar mesmo a estrutura do BD.
Minha necessidade é de puxar apenas uma vez o nome e o restante dos dados e 'venc_parc02' que é um alilas precisaria aparecer assim mas o concat ta falhando na hora de formatar a data.naquele exemplo foi o resultado que consegui até agora. só preciso substituir o concat, mas nada o restante pode ignorar.Só queria uma função para desagregar o 'venc_parc02' para o resultado ser este.

Carlos Barão 12/06/2015 21/07/2015 21/08/2015

Márcio André 30/06/2015 30/07/2015 30/08/2015 30/09/2015 30/10/2015
GOSTEI 0
Marcos P

Marcos P

30/05/2015

É isso ?
SELECT nome_pac,
GROUP_CONCAT(venc_parcelas) AS 'venc_parc02'
FROM paciente inner join financeira on paciente.id = financeira.id_pac 
where status=1
GROUP BY paciente.id
ORDER BY nome_pac ASC 
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

30/05/2015

Antes de mudar a estrutura do banco, você tem que verificar o impacto que isso irá causar.
Realmente, observei os campos que constam no cadastro de clientes e tem informações de venda, aonde deveria constar apenas os dados dos clientes.
Isso deveria ter sido normalizado no momento da modelagem dos dados.
Esse sistema já está implantado?
GOSTEI 0
Márcio

Márcio

30/05/2015

Peguei o sistema para fazer algumas mudança as informações de compra da tabela paciente não são manipuláveis, são apenas informações que vão para o banco de dados quando o cliente estiver inativo. Agora a tabela financeira sei que tem que melhorar tipos de campos e mais algumas coisas.
O impacto está sendo avaliado pois não estou achando solução para o problema até já mostrei outro esboço para o cliente no qual aparece do jeito que ele quer, mas com um ponteiro no id. Assim aparece resultado único mas com eficiência.
Eu ainda não tinha me deparado com um problema igual e nunca achei que seria tão difícil a resolução.
GOSTEI 0
Márcio

Márcio

30/05/2015

Usando o GROUP CONCAT não é possivél ter um resultado satisfatório pois data se transforma em string e não se formata com precisão. E isso pode comprometer a estabilidade do sistema.
O milagre era só substituir o group concat por uma função que desagregasse o campo 'venc_parcelas'.
Mas agradeço o esforço e agora que conheço o fórum estou sempre a disposição se eu puder ajudar .
GOSTEI 0
Marcos P

Marcos P

30/05/2015

marcim,

Continuo não entendo o resultado final que você precisa...

É isso que você precisa ?

Carlos Barão 12/06/2015 
Carlos Barão 21/07/2015 
Carlos Barão 21/08/2015
Márcio André 30/06/2015 
Márcio André 30/07/2015 
Márcio André 30/08/2015 
Márcio André 30/09/2015 
Márcio André 30/10/2015 
GOSTEI 0
Márcio

Márcio

30/05/2015

É isso que preciso sem group concat: Entendeu?

Carlos Barão 12/06/2015 21/07/2015 21/08/2015

Márcio André 30/06/2015 30/07/2015 30/08/2015 30/09/2015 30/10/2015

SIMPLES ASSIM
GOSTEI 0
Marcos P

Marcos P

30/05/2015

Se você obtiver o resultado como coloquei acima...
Carlos Barão   12/06/2015 
Carlos Barão   21/07/2015 
Carlos Barão   21/08/2015
Márcio André   30/06/2015 
Márcio André   30/07/2015 
Márcio André   30/08/2015 
Márcio André   30/09/2015 
Márcio André   30/10/2015 

Gerar a saída nesse formato, com a coluna de datas do tipo "date", resolveria seu problema ?

Suas strings de data estão sempre no formato "dd/mm/aaaa" ?
GOSTEI 0
Márcio

Márcio

30/05/2015

Este resultado foi o primeiro que alcancei porem quando gero o relatorio o nome também aparece veja a imagem que postei de um resultado se eu fizer assim como tá sugerindo para cada vencimento aparece uma todos os outros dado a unica solução aceitável e parece que não é possível pelo fato de agregar e depois desagregar é a ultima que postei esta abaixo.estou analisando e depurando o impacto que vai ter a mudança de estrutura do BD sendo que já possui dados na tabela original em uso.

Carlos Barão 12/06/2015 21/07/2015 21/08/2015

Márcio André 30/06/2015 30/07/2015 30/08/2015 30/09/2015 30/10/2015
GOSTEI 0
Márcio

Márcio

30/05/2015

Os formatos de datas estão padrão MYSQL para poder manipular depois eu faço a formatação na saida ou entrada da query.
Pode ver no exemplo da tabela que estão padrão.
GOSTEI 0
Marcos P

Marcos P

30/05/2015


Usando o GROUP CONCAT não é possível ter um resultado satisfatório pois data se transforma em string e não se formata com precisão. E isso pode comprometer a estabilidade do sistema.
O milagre era só substituir o group concat por uma função que desagregasse o campo 'venc_parcelas'.


Sempre que você gerar um GROUP_CONCAT, a saída será gerada como string, por conta do separador entre os valores.

Considerando que as colunas são do tipo "Date" na origem, qual exatamente sua preocupação em relação ao formato não ser gerado com precisão no momento da concatenação ?

Mesmo gerando uma string, você consegue definir exatamente o formato de saída das datas ( via DATE_FORMAT ), padronizando-os.

Ainda, é possível definir o caracter de separação para identificar as diversas ocorrências de data, dentro da linha...

Datas nulas ( ou eventualmente inválidas ), você consegue tratar no WHERE... desprezando-as .

SELECT nome_pac,
GROUP_CONCAT(DATE_FORMAT(venc_parcelas,'%d-%m-%Y') SEPARATOR ';') AS 'venc_parc02'
FROM paciente inner join financeira on paciente.id = financeira.id_pac 
where status=1
GROUP BY paciente.id
ORDER BY nome_pac ASC 


Se você quiser gerar ocorrências individuais das datas, para tratá-las como campos separados no form da aplicação, gere o group simples com as datas :

SELECT  DISTINCT paciente.id, paciente.Nome_pac, DATE_FORMAT(venc_parcelas,'%d-%m-%Y') AS 'venc_parc02'
FROM paciente inner join financeira on paciente.id = financeira.id_pac 
where status=1
GROUP BY paciente.id, paciente.Nome_pac, DATE_FORMAT(venc_parcelas,'%Y-%m-%d')
ORDER BY paciente.id,venc_parcelas


E depois coloque os valores separados do lado da aplicação...
( talvez uma grid, ficasse melhor para relacionar as parcelas )
[img]http://arquivo.devmedia.com.br/forum/imagem/378439-20150601-194439.png[/img]

Não descarte tratar isso na aplicação... pode ser a melhor solução !
GOSTEI 0
Márcio

Márcio

30/05/2015

Olha este resultado que vc postou está perfeito e isso que preciso estou fazendo as mudanças na aplicação e format na query está resolvido.
Obrigado todos que contribuíram.
GOSTEI 0
Marcos P

Marcos P

30/05/2015

Ótimo que resolveu...
GOSTEI 0
Márcio

Márcio

30/05/2015

Estou mudando um pouco a aplicação o resultado da query continua insatisfatório mas vc me abriu outra porta estou tratando a plicação com java script e vou ver no que vai dar.
Mas as formatações de datas me ajudou muito obrigado.
GOSTEI 0
Márcio

Márcio

30/05/2015

Galera venho aqui agradecer ao fórum e ressaltar os colegas Marisiana e ao Marcos P pela ajuda prestada.
E também mostrar o resultado que está satisfatório e que foi fruto da boa vontade e paciência dos colegas do fórum.

[img]http://arquivo.devmedia.com.br/forum/imagem/433925-20150604-171344.png[/img]


Obrigado...
GOSTEI 0
Marcos P

Marcos P

30/05/2015

Marcim,

Se todos tivessem sua preocupação de retornar aos posts e informar o resultado final, nosso fórum seria muito melhor !

Parabéns e retorne por aqui, sempre que for possível !
GOSTEI 1
Marisiana Battistella

Marisiana Battistella

30/05/2015

Obrigada pelo feedback Marcim!!
Fico feliz em poder contribuir.! =)
GOSTEI 1
POSTAR