Bom dia.
Preciso fazer uma estatística de atendimento de ocorrências e para isso preciso retornar pelo comando select o model e o count(m), ao fazê-lo recebo a mensagem de que não é possível retornar dois tipos de dados, executando o comando no pgAdmin o comando executa perfeitamente da forma que pretendo utilizar. Isso me faz pensar que deva ter outro jeito de realizar o que preciso, alguém saberia a melhor forma de fazer isso?
publicList<MovimentacaoVTR>teste(){TypedQuery<MovimentacaoVTR>query=manager.createQuery("SELECT count(m) as quantidade, m.codigoOcorrencia FROM MovimentacaoVTR as m GROUP BY m.codigoOcorrencia",MovimentacaoVTR.class); returnquery.getResultList();
}
A função COUNT é uma função agregadora. Em SQL, uma função agregadora é aquela que permite executar uma operação aritmética nos valores de uma determinada coluna em todos os registros de uma tabela. Como executam sobre todos os registros, trazem um valor único representado pelo resultado dessa operação aritmética. Por esse motivo, são conhecidas como operações agregadoras.
No seu caso, pode usar criar uma união de consultas. Por exemplo:
Achei interessante a primeira solução, o UNION mas pelo que vi ele não tem suporte no jpql mas mesmo assim, como eu faria para que o count(m) ficasse em uma coluna separada?
No caso da subconsulta recebo o seguinte erro no pgAdmin “more than one row returned by a subquery used as an expression”
Pode me dar uma luz quanto a isso?
I
Iohannes
Eu não sei se no JPQL tem o ‘comando’ LIMIT que permite limitar quantos retornos uma
consulta irá ter. Por exemplo:
Sua solução acima funciona no postgreSql mas ao implementá-la na classe repositorio alterando o Limit 1 que não foi reconhecido no JPQL pelo distinct recebo o mesmo erro que eu recebia:
Penso que o erro está no retorno onde estou usando uma List mas não tenho certeza:
publicList<MovimentacaoVTR>todos(){
I
Iohannes
De acordo com a exceção lançada: “Não é possível criar TypedQuery para consulta com mais de um retorno usando o tipo de resultado solicitado”. Não tem acesso a documentação do JPQL? Eu nunca o usei… então não posso ajudar.
P
pmlm
Assumindo que MovimentacaoVTR tem campos codigoOcorrencia e countCodigoOcorrencia:
publicMovimentacaoVTR(StringcodigoOcorrencia,Longcontagem){this.codigoOcorrencia=codigoOcorrencia;this.countCodigoOcorrencia=contagem;// não tenho certeza se deva ser Long}
A
Agent_K
Bom dia!
@pmlm achei muito interessante o conceito do uso do SELECT new, eu não conhecia, ele possibilita o retorno de mais de um elemento até então limitado pelo TypedQuery. Agora estou tendo um problema com a Entidade MovimentaçãoVTR que na anotação @Entity tenho o seguinte erro:
The Java class for mapped type "MovimentacaoVTR" must define a non-private zero-argument constructor
Outra coisa, não tenho o campo countCodigoOcorrencia na Entidade MovimentacaoVTR, penso que o valor contido nela seria aleatório e não sei se seria uma boa prática ter esse campo, estou enganado?
Para ficar mais claro o campo m.codigoOcorrencia é um relacionamento @ManyToOne. Será que há como contornar isso?
P
Solucao aceita
pmlm
Todas as classes Java, se não tiverem um construtor definido, definem um por omissão. Ao criar o teu construtor estás a “esconder” esse, pelo que deves declarar também o construtor vazio
publicMovimentacaoVTR(){}
Se queres devolver o valor da contagem, ele tem de ser escrito em algum lado. Nesse caso, podes usar campos transient, que servem para estes propósitos de valores que não são guardados na BD mas podem ser de alguma forma calculados.
@TransientprivateLongcountCodigoOcorrencia;
Se o codigoOcorrencia é uma entidade e não uma String só tens de alterar o construtor para receber um objecto desse tipo e não uma String
A
Agent_K1 like
@pmlm Fiz a implementação e funcionou perfeitamente no meu caso. Obrigado!!