André, boa tarde. O datatype do campo da primeira pergunta é timestamp; O median que o Chiappa explicou é a mediana da matemática, o primo do moda, lembram ??? Por exemplo, você tem três valores (1, 5, 7), ele retornaria 5 (A média aritmética daria 4,333...), no meu caso eu preciso da média aritmética realmente, ou seja, a soma de todos valores dividido pelo total de valores.
Exemplo bem tosco do median: select median(a.valor) from (select 1 valor from dual union select 5 valor from dual union select 7 valor from dual) a Sem querer eu acho que achei um jeito mais simples de resolver o meu problema e que eu também pequei em não informar, na tabela eu tenho dois campos que são "date", a média que preciso é da diferença desses dois campos, quando subtraimos uma data de outra data o datatype que é retornado é um integer, correto ?? Sendo int, eu consigo fazer o avg e depois só tenho que formatar isso em dias, horas, minutos e segundos. Em Segunda-feira, 16 de Dezembro de 2013 14:10, Andre Santos <[email protected]> escreveu: 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.
