Banco Firebird (Problemas ao retornar apenas o primeiro registro)

03/09/2015

0

Bom dia Prezados,

Estou tentando retornar apenas o maior registro do ORDXFUN na consulta abaixo, porém não estou conseguindo, vocês poderiam me ajudar?

select
ORDSERV.TAG AS OS, ORDSERV.DATPRO2 AS DATA,
USER_ANALIS.U_DESCRICA AS ANALISE,
MAX (ORDXFUN.DATHORFIM) AS DATHORFIM

from ORDSERV

inner join USER_ANALIS on ORDSERV.R_USER_ANALIS_U_PK_REDUZIDO=USER_ANALIS.U_PK_REDUZIDO
inner join ORDXFUN ON ORDXFUN.CODEMP=ORDSERV.CODEMP AND ORDXFUN.CODORD=ORDSERV.CODORD

WHERE ORDSERV.STATORD = 'A'
GROUP BY ORDSERV.TAG, ORDSERV.DATPRO2, USER_ANALIS.U_DESCRICA, ORDXFUN.DATHORFIM

Retorno:

[img]http://arquivo.devmedia.com.br/forum/imagem/451341-20150903-100122.jpg[/img]
João Cristo

João Cristo

Responder

Posts

03/09/2015

Fabio Basso

create table teste_data (
id_teste_data integer not null,
datahora timestamp,
data date,
primary key (id_teste_data));


insert into teste_data values (1, '09/03/2015 10:00:00', '09/03/2015');
insert into teste_data values (2, '09/03/2015 11:00:00', '09/03/2015');
insert into teste_data values (3, '09/03/2015 12:00:00', '09/03/2015');
insert into teste_data values (4, '09/04/2015 10:01:00', '09/04/2015');
insert into teste_data values (5, '09/04/2015 10:01:01', '09/04/2015');
insert into teste_data values (6, '09/04/2015 10:01:02', '09/04/2015');

select * from teste_data;
select data, max(datahora)
from teste_data
group by data;


Neste exemplo acima, o resultado será sempre a última hora, agrupado por dia.

No exemplo que vc mandou, foi agrupado pelo campo ORDXFUN.DATHORFIM , e eu acho que este campo está armazenando data e hora, então ele não vai apenas um horário, pois não está agrupado apenas pelo dia.
Responder

03/09/2015

João Cristo

Desculpe a ignorância Fabio, entendi a consulta pelo seu select, porém, não sei como modificar o meu para obter o resultado.
Responder

03/09/2015

Fabio Basso

Tenta isso (alterei o último campo da sua cláusula group by):
select
ORDSERV.TAG AS OS, ORDSERV.DATPRO2 AS DATA,
USER_ANALIS.U_DESCRICA AS ANALISE,
MAX (ORDXFUN.DATHORFIM) AS DATHORFIM

from ORDSERV

inner join USER_ANALIS on ORDSERV.R_USER_ANALIS_U_PK_REDUZIDO=USER_ANALIS.U_PK_REDUZIDO
inner join ORDXFUN ON ORDXFUN.CODEMP=ORDSERV.CODEMP AND ORDXFUN.CODORD=ORDSERV.CODORD

WHERE ORDSERV.STATORD = 'A'
GROUP BY ORDSERV.TAG, ORDSERV.DATPRO2, USER_ANALIS.U_DESCRICA, ORDSERV.DATPRO2
Responder

03/09/2015

João Cristo

Funcionou perfeitamente Fábio, porém, quando adiciono o cálculo que você tinha me ajudado não consigo retornar apenas um registro e também não consegui arredondar o tempototal com Cast.

SELECT
ORDSERV.TAG AS OS,
ORDSERV.DATPRO, MIN(ORDXFUN.DATHORINI) AS DATHORINI, MAX(ORDXFUN.DATHORFIM) AS DATHORFIM,
datediff(hour, ORDSERV.DATPRO, ORDXFUN.DATHORINI) || ':' ||mod(datediff (minute, ORDSERV.DATPRO, ORDXFUN.DATHORINI), 60) as tempototal

FROM ORDSERV
inner join USER_ANALIS on ORDSERV.R_USER_ANALIS_U_PK_REDUZIDO=USER_ANALIS.U_PK_REDUZIDO
inner join ORDXFUN ON ORDXFUN.CODEMP=ORDSERV.CODEMP AND ORDXFUN.CODORD=ORDSERV.CODORD

WHERE ORDSERV.STATORD='A'

AND ORDSERV.CODEMP=:CODEMP
GROUP BY ORDSERV.TAG, USER_ANALIS.U_DESCRICA, ORDSERV.DATPRO, ORDXFUN.DATHORFIM, ORDXFUN.DATHORINI
ORDER BY 1

Retorno:

[img]http://arquivo.devmedia.com.br/forum/imagem/451341-20150903-115602.jpg[/img]
Responder

03/09/2015

Fabio Basso

João,

Você está agrupando novamente por ORDXFUN.DATHORINI, vc precisa agrupar por ORDSERV.DATPRO2.

Quanto aos zeros, eu não consegui simular isso aqui. Tem como vc postar os tipos de dados dessas tabelas (O DDL das tabelas, ou seja o código fonte de criação das tabelas)?
Responder

03/09/2015

João Cristo

Tentei agrupar pela ORDSERV.DATPRO2 e retornou o erro, vou verificar o código fonte mais os campos de datas são todos TIMESTAMP.

SELECT
ORDSERV.TAG AS OS,
ORDSERV.DATPRO, MIN(ORDXFUN.DATHORINI) AS DATHORINI, MAX(ORDXFUN.DATHORFIM) AS DATHORFIM,
datediff(hour, ORDSERV.DATPRO, ORDXFUN.DATHORINI) || ':' ||mod(datediff (minute, ORDSERV.DATPRO, ORDXFUN.DATHORINI), 60) as tempototal

FROM ORDSERV
inner join USER_ANALIS on ORDSERV.R_USER_ANALIS_U_PK_REDUZIDO=USER_ANALIS.U_PK_REDUZIDO
inner join ORDXFUN ON ORDXFUN.CODEMP=ORDSERV.CODEMP AND ORDXFUN.CODORD=ORDSERV.CODORD

WHERE ORDSERV.STATORD='F'

AND ORDSERV.CODEMP=:CODEMP
GROUP BY ORDSERV.TAG, ORDSERV.DATPRO2, USER_ANALIS.U_DESCRICA, ORDSERV.DATPRO2
ORDER BY 1

Retorno:

[img]http://arquivo.devmedia.com.br/forum/imagem/451341-20150903-170624.jpg[/img]
Responder

04/09/2015

João Cristo

Acho que não estou entendo certo o GROUP BY, não é necessário inserir todos os campos que compõe o select?
Responder

04/09/2015

Fabio Basso

Não, você indica quais campos serão agrupados. Por exemplo, se eu quiser somar o total de contas a receber e agrupar por cliente, ficaria assim:
select nome_cliente, sum(contareceber.valor_pendente) as valor_pendente
from cliente join contareceber on (cliente.id_cliente = contareceber.id_cliente)
group by nome_cliente
Responder

04/09/2015

João Cristo

Ok, mais quando tentei agrupar pela DATPRO2 retornou o erro:

Dynamic SQL Error
SQL error code = -104
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)
Responder

04/09/2015

Fabio Basso

Copiei as linhas abaixo do seu código:

SELECT ORDSERV.TAG AS OS, ORDSERV.DATPRO, MIN(ORDXFUN.DATHORINI) AS DATHORINI, MAX(ORDXFUN.DATHORFIM) AS DATHORFIM,
datediff(hour, ORDSERV.DATPRO, ORDXFUN.DATHORINI) || ':' ||mod(datediff (minute, ORDSERV.DATPRO, ORDXFUN.DATHORINI), 60) as tempototal

GROUP BY ORDSERV.TAG, ORDSERV.DATPRO2, USER_ANALIS.U_DESCRICA, ORDSERV.DATPRO2


O GROUP BY tem que ser na mesma sequência do select:
SELECT ORDSERV.TAG AS OS, ORDSERV.DATPRO, MIN(ORDXFUN.DATHORINI) AS DATHORINI, MAX(ORDXFUN.DATHORFIM) AS DATHORFIM,
GROUP BY ORDSERV.TAG, ORDSERV.DATPRO2, USER_ANALIS.U_DESCRICA, ORDSERV.DATPRO2

repare que o DATPRO2 não está definido no SELECT
Responder

04/09/2015

João Cristo

Desculpa, fiz uma confusão com as consultas, esta abaixo é a correta. Fiz o agrupamento seguindo a ordem mas ainda retorna erro.

SELECT
ORDSERV.TAG, ORDSERV.DATPRO,
USER_ANALIS.U_DESCRICA AS ANALISE,

MIN (ORDXFUN.DATHORINI) AS DATHORINI,
MAX (ORDXFUN.DATHORFIM) AS DATHORFIM,
SUM(ORDXFUN.DATHORFIM - ORDXFUN.DATHORINI)*24 AS TOTALHORAS,
datediff(hour, ORDSERV.DATPRO, ORDXFUN.DATHORINI) || ':' ||mod(datediff (minute, ORDSERV.DATPRO, ORDXFUN.DATHORINI), 60) as tempototal


from ORDSERV

inner join USER_ANALIS on ORDSERV.R_USER_ANALIS_U_PK_REDUZIDO=USER_ANALIS.U_PK_REDUZIDO
inner join ORDXFUN ON ORDXFUN.CODEMP=ORDSERV.CODEMP AND ORDXFUN.CODORD=ORDSERV.CODORD

WHERE ORDSERV.STATORD = 'F'
GROUP BY ORDSERV.TAG, ORDSERV.DATPRO, USER_ANALIS.U_DESCRICA

Erro:

Dynamic SQL Error
SQL error code = -104
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)
Responder

04/09/2015

Fabio Basso

Acho que é por causa dessa última linha do select:
datediff(hour, ORDSERV.DATPRO, ORDXFUN.DATHORINI) || ':' ||mod(datediff (minute, ORDSERV.DATPRO, ORDXFUN.DATHORINI), 60) as tempototal

não tem nenhum código de agrupamento(SUM por exemplo) para este campo.
Responder

04/09/2015

João Cristo

Ok, mais preciso da diferença de horas/minutos entre a ORDSERV.DATPRO e o menor registro da ORDXFUN, como faço ?
Responder

04/09/2015

Fabio Basso

Não consigo responder isso de imediato, eu teria que fazer uns testes direto no banco também. É possível vc me mandar uma cópia do banco para eu testar?
Responder

04/09/2015

João Cristo

Infelizmente meu acesso é restrito, não consigo backup ou cópia do banco. A estrutura da tabela consegui alguns campos.

[img]http://arquivo.devmedia.com.br/forum/imagem/451341-20150904-103821.jpg[/img]

[img]http://arquivo.devmedia.com.br/forum/imagem/451341-20150904-103829.jpg[/img]
Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar