Tiago Não consegui ainda analisar com detalhe, mas deixo 2 comentários:
- no select mais interno, se o campo já for do tipo DATE, não precisaria fazer as conversões [to_date(to_char(hora, 'dd/mm/rrrr hh24:mi:ss'),'dd/mm/rrrr hh24:mi:ss') dt]. Qual é o datatype de "hora", neste exemplo? - Essa consulta toda não traria o mesmo resultado que a função MEDIAN (que o Chiappa indicou)? Faça uns testes para comparar. [ ]'s André Em 13 de dezembro de 2013 11:32, Tiago de Assis Pimenta < [email protected]> escreveu: > > > Pessoal, um colega aqui do trabalho chegou a essa solução: > > > Em Sexta-feira, 6 de Dezembro de 2013 21:21, Andre Santos < > [email protected]> escreveu: > > Chiappa > > Super dica essa da função MEDIAN ! Muito bom!!! Valeu! :) > Por curiosidade, fui procurar nas documentações e vi que ela existe desde > a versão 10g (10.1). > > Tiago, se a gente seguir a lógica da função AVG, realmente não é possível > usar tipo DATE ou TIMESTAMP... pois não se pode somar datas e nem > dividí-las. Então o algoritmo para achar uma "data/hora média" (ou > "mediana") tem de ser outro mesmo. > > [ ]'s > > André > > > > Em 6 de dezembro de 2013 17:49, J. Laurindo Chiappa < > [email protected]> escreveu: > > > okdoc : Sobre a MEDIAN, veja lá na doc que é dito que é via Ordenação, > então deduzo que o algoritmo seja , uma vez obtido o menor e o maior valor > através dessa ordenação, se calcula a DIFERENÇA entre esses dois pontos, > veja o meu exemplo que parece que é isso mesmo que ele faz... > Se não é isso que vc precisa, aí é mesmo partir pra conversão para > number/aritmética de datas e similares pra poder usar a AVG.... > > > []s > > Chiappa > > --- Em [email protected], Tiago de Assis Pimenta <tiagopimenta@...> > escreveu > > > > Chiappa, > > > > Eu tentava ver a versão executando o "select * from v$version", e não > tinha acesso, vou tentar via sql*plus. > > > > Quanto ao MEDIAN, vou dar uma olhada com carinho na documentação para > ver como ele faz a média sem fazer a soma, pois no meu caso seria a média > aritimética simples, ou seja, se tivesse 3 registros com os seguintes > dados "01:00:00", "02:00:00", "03:00:00", a média seria a soma de todos os > valores e dividir pela quantidade total de registros (3), exatamente como o > AVG faz. > > > > Obrigado. > > > > > > > > Em Sexta-feira, 6 de Dezembro de 2013 18:22, J. Laurindo Chiappa > <jlchiappa@...> escreveu: > > > > > > > Tiago, em verdade a não ser que o teu DBA seja tão retentivo que não te > dê acesso nem sequer ao sqlplus, ele não toca Apito nenhum na identificação > de versão - basta vc conectar no sqlplus com um usuário qualquer que > NECESSARIAMENTE vc já recebe a versão Exata do database , veja : > > > > [oracle@localhost ~]$ sqlplus zemane/lixao > > > > SQL*Plus: Release 11.2.0.2.0 Production on Fri Dec 6 17:57:02 2013 > > > > Copyright (c) 1982, 2010, Oracle. All rights reserved. > > > > Connected to: > > Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production > > With the Partitioning, OLAP, Data Mining and Real Application Testing > options > > > > SQL> > > > > ==> tá aí, no caso conectei num banco 11.2.0.2.0 , e como os primeiros > dígitos são a versão major e os segundos são o release, sei que estou num > 11G R2, yep ??? > > > > André , a coisa é assim : eu lembrava que a Documentação do 11gr2 (a > versão que assumo sempre) dizia que a AVG aceita NUMBERs (inclusive porque > a lógica que ela aplica é somar os valores todos e depois dividir pela > qtdade de valores presentes, média aritmetica simples), *** MAS TAMBÉM **** > datatypes que possam ser convertidos para NUMBER, o que em tese é o caso de > um DATE, ele é um NUMBER disfarçado, é isso que permite a Aritmética de > datas, inclusive.... Por isso que achei que era possível se trabalhar com > DATEs, no caso do colega transformando o TIMESTAMP em DATE... > > De curiosidade, porém, eu fui fazer o teste nesse mesmo banco da versão > acima e a minha idéia não se aplica : > > > > SQL> alter session set NLS_DATE_FORMAT='dd/mm/yyyy hh24:mi:ss'; > > > > Session altered. > > > > SQL> alter session set NLS_TIMESTAMP_FORMAT='dd/mm/yyyy hh24:mi:ss.ff'; > > > > Session altered. > > > > SQL> create table TAB_TEST1 (c1 date); > > > > Table created. > > > > SQL> insert into TAB_TEST1 values(to_date('01/10/2013 10:10:10', > 'dd/mm/yyyy hh24:mi:ss')); > > > > 1 row created. > > > > SQL> insert into TAB_TEST1 values(to_date('03/12/2013 20:20:20', > 'dd/mm/yyyy hh24:mi:ss')); > > > > 1 row created. > > > > SQL> select avg(c1) from TAB_TEST1; > > select avg(c1) from TAB_TEST1 > > * > > ERROR at line 1: > > ORA-00932: inconsistent datatypes: expected NUMBER got DATE > > > > ==> então Realmente, para ter a média aritmética via AVG seria > necessário se fazer Explicitamente a conversão do DATE para NUMBER, seja > via CAST, TO_NUMBER(colunadate, 'J'), aritmética de datas (subtraindo > SYSDATE, sei lá), algo do tipo ... > > > > Agora : também consultando a documentação 11gr2, eu vi que ela dispõe de > uma OUTRA função de cálculo de médias, chamada MEDIAN, que eu não conhecia > das versões anteriores : a documentação aponta que essa sujeita não faz > soma, mas sim Ordena , então funciona para DATEs ** e ** para TIMESTAMPs : > > > > SQL> select median(c1) from TAB_TEST1; > > > > MEDIAN(C1) > > ------------------- > > 02/11/2013 03:15:14 > > > > SQL> > > > > SQL> create table TAB_TESTE2 (c1 timestamp); > > > > Table created. > > > > SQL> insert into TAB_TESTE2 values(to_timestamp('01/10/2013 > 10:10:10.111111', 'dd/mm/yyyy hh24:mi:ss.ff')); > > > > 1 row created. > > > > SQL> insert into TAB_TESTE2 values(to_timestamp('03/12/2013 > 20:20:20.333333', 'dd/mm/yyyy hh24:mi:ss.ff')); > > > > 1 row created. > > > > SQL> select median(c1) from tab_teste2; > > > > MEDIAN(C1) > > ---------------------------------------------------------- > > 02/11/2013 03:15:15.222222 > > > > SQL> > > > > ==> OU SEJA, muda a minha Orientação para o Tiago, que passa a ser : se > no seu exato release lá dele estiver presente a MEDIAN, E SE a lógica dela > que não faz soma, atende, é Experimentar a MEDIAN.... > > > > []s > > > > Chiappa > > > > --- Em [email protected], Tiago de Assis Pimenta > <tiagopimenta@> escreveu > > > > > > > Concordo com você Chiappa, pena que o DBA aqui da empresa não concorde > com isso, enfim, agradeço sua ajuda, já deu uma luz aqui para mim. > > > > > > > > > > > > Em Sexta-feira, 6 de Dezembro de 2013 14:26, Andre Santos > <andre.psantos.ti@> escreveu: > > > > > > > > > > Pessoal > > > > > > Por favor, corrijam-me se eu estiver errado... mas acho que AVG também > não aceita valores "date" (aí não adiantaria usar CAST...). > > > > > > > > > Teria de definir uma lógica (transformando tipos), como o Chiappa > sugeriu. > > > > > > > > > [ ]'s > > > > > > André > > > > > > > > > > > > > > > > > > Em 6 de dezembro de 2013 12:35, J. Laurindo Chiappa <jlchiappa@> > escreveu: > > > > > > > > > > > > > > >Então : quando vc desenvolve para / utiliza um RDBMS, vc ** > OBRIGATORIAMENTE ** tem que saber pelo menos o Release além da versão-alvo > :não basta só falar "ah, é 11G", pois EXISTEM SIM diferenças Significativas > em diversos casos entre um 11G R1 e um 11G R2, yep ?? > > > >No ponto Específico que vc pergunta, porém, não há diferença > significativa, pois afaik ambos ( 11Gr1 E 11gr2) Não Possuem uma > função/built-in específico para médias de timestamp - LEVANTE porém a > versão e release que vc usa efetivamente, consulte a Doc para confirmar mas > iirc é isso mesmo... > > > > > > > > > > > >[]s > > > > > > > >Chiappa > > > > > > > >--- Em [email protected], Tiago de Assis Pimenta > <tiagopimenta@> escreveu > > > >> > > > > > > > >> Chiappa, > > > >> > > > >> A versão **EXATA** eu não tenho, mas é a 11G e eu tinha pensado > realmente em transformar tudo em segundos, fazer a média e depois converter > de volta, mas tinha esperança que existisse uma função analítica ou algo > parecido que fizesse a média. > > > >> > > > >> Abs > > > >> > > > >> > > > >> > > > > > > > > Em Sexta-feira, 6 de Dezembro de 2013 10:54, J. Laurindo Chiappa > <jlchiappa@> escreveu: > > > > > > > >> > > > >> > > > >> Bem, como vc não nos dá a ** versão exata ** do RDBMS em questão > pode haver variações (** CONSULTE ** a documentação da sua versão para > confirmar ou negar) , mas de modo geral afaik a função que calcula médias > aritméticas, a AVG, ainda não aceita timestamps, apenas DATEs e NUMBERs : > assim, se vc não precisa da fração de segundos no seu cálculo de média, vc > simplesmente transforma na sua query os TIMESTAMPs em DATEs (via CAST ou > demais funções de conversão)... Já se vc Precisa da fração de segundos, aí > imho o melhor procedimento seria transformar em NUMBER o timestamp (número > de segundos, certamente) via extract(second from colunatimestamp) , e aí a > expressão para cálculo seria algo tipo : select avg(extract(second from > colunatimestamp) ...... > > > >> Claro, isso te dá o número de segundos, SE vc quisesse ter dias, > horas, minutos, E segundos (com fração), provavelmente divide o inteiro de > segundos por 86400, o inteiro se segundos por 3600 para obter horas, é > isso, creio.... > > > >> Não testei, escrevo de cabeça, mas deve ser algo MUITO muito > próximo, veja aí.... > > > >> > > > >> ´[]s > > > >> > > > >> Chiappa > > > >> > > > > > > > > --- Em [email protected], Tiago de Assis Pimenta > <tiagopimenta@> escreveu > > > > > > > >> > > > > >> > Pessoal, bom dia. > > > >> > > > > >> > Preciso fazer a média de um campo timestamp e gostaria de saber > se alguém já fez isso ? Qual a melhor maneira de se fazer ? > > > >> > > > > >> > Abraços > > > >> > > > > >> > > > > > > > > > > > > > > > > > > > select id, > first_dt + avg(dt - first_dt) avg_dt, > avg(dt - first_dt) * 60 > from (select id, > dt, > first_value(dt) over(partition by id) first_dt > from (select id, > to_date(to_char(hora, 'dd/mm/rrrr > hh24:mi:ss'),'dd/mm/rrrr hh24:mi:ss') dt > from tiago)) > group by id, first_dt; > > Aparentemente, nos testes que fizemos, deu certo, ai queria compartilhar > essa solução e ouvir um possível problema que esse select poderá ter. > > Abraços. > > >
