Pular para o conteúdo
Visualizando 15 posts - 1 até 15 (de 16 do total)
  • Autor
    Posts
  • #95997
    batofao
    Participante

      bom dia,

      estou rodando esse select, e o mesmo me fala que a sub consulta retorna mais de uma linha, sabem como posso fazer da maneira correta?

      obg

      select a.cod_produto,
      a.data,
      a.valor,
      (select (valor/a.valor)-1 from cotacoes where add_months(a.data,1) = cotacoes.data)
      from cotacoes a;

      #96003
      burga
      Participante

        Vamos chutar denovo, cada produto só tem uma cotação em uma determinada data?

        Se sim, coloque o cod_produto da consulta externa comparando na consulta interna também…

        select a.cod_produto,
        a.data,
        a.valor,
        (select (valor/a.valor)-1 from cotacoes where add_months(a.data,1) = cotacoes.data AND a.cod_produto = cotacoes.cod_produto)
        from cotacoes a;

        #96004
        batofao
        Participante

          isso mesmo,

          muito obrigado… 😀

          #96027
          batofao
          Participante

            me tire uma duvida como eu estou trabalhando só com os ultimos dias ulteis de cada mes se eu faço:

            select a.cod_produto,
            a.data,
            a.valor,
            (select (valor/a.valor)-1 from cotacoes where add_months(a.data,1) = cotacoes.data AND a.cod_produto = cotacoes.cod_produto)
            from cotacoes a;

            pode acontecer o seguinte ele vai pegar por exemplo dia 30 de maio e vai subtrair um mes certo,dia 30 de abril, por exemplo
            mas o que pode acontecer é o seguinte se esse dia 30 de abril forum sabado, domingo ou feriado, então essa data não é valida p mim,
            então mais especificamente preciso que ele selecione ultima data ultil do mes passado, sera que consigo fazer isso só com esse select.

            so uma observação esse select acima funciona perfeitamente só que quando acontece essa excessão ele me retorna um valor (null), pq eu não tenho essa data

            obrigado

            #96028
            jspaulonci
            Participante

              Tô falando !!!! Burga vc é nosso guru de sql, e deixa de modestia heim.

              kkkkkkkkkkkkk

              abraços

              #96029
              batofao
              Participante

                não sei se consegui explicar bem no topico acima.

                obg

                #96030
                burga
                Participante

                  Hummm, me lembro desse problema do ultimo dia útil do mês…

                  Até então, conseguimos resolver esse problema de pegar os ultimos dias úteis de cada mês, então vou assumir que este filtro já está pronto.
                  Sendo assim, só deve existir um dia por mês na sua tabela (o ultimo dia util), sabendo disso, você pode truncar as datas por mês com trunc(data,’MM’) antes de comparar ou transformar em to_char(data,’mm/yyyy’).

                  select a.cod_produto,
                  a.data,
                  a.valor,
                  (select (valor/a.valor)-1
                  from cotacoes
                  where trunc(add_months(a.data,1),’MM’) = trunc(cotacoes.data,’MM’)
                  AND a.cod_produto = cotacoes.cod_produto)
                  from cotacoes a;

                  [quote=”jspaulonci”:3q1223bm]Tô falando !!!! Burga vc é nosso guru de sql, e deixa de modestia heim.

                  kkkkkkkkkkkkk

                  abraços[/quote]

                  É João,
                  em SQL ainda consigo me virar, mas pra DBA mesmo ainda falta muito, mas estou estudando… 😳

                  #96031
                  batofao
                  Participante

                    fiz a consulta, e ele fala que a consulta de uma linha retorna mais valores,
                    porem na linha que colocamos o select (valor/a.valor)-1, eu coloquei um select max(a.data) só para ver se ele me retorna a data certa, e foi isso que aconteceu, todas as datas conferem , preciso fazer agora ele me retornar o valor, sera que tenho que fazer mais um select dentro dele colocando um where a.data in ( todo select feito)

                    vou testar isso mais não sei se vai resolver..

                    valeu..

                    #96032
                    batofao
                    Participante

                      consegui,

                      bom não sei se esse é o modo mais correto, mas estou chegando no resultado final entre todas aquelas consultas que fizemos anteriormente consegui chegar nesse resultado olha como ficou :

                      select zx.nome_cliente, zx.nome_do_fundo, co.data, co.valor
                      ,(select max(co.valor/x.valor) -1 from cotacoes x
                      where trunc(add_months(co.data,-1),’MM’) = trunc(x.data,’MM’) AND co.cod_produto = x.cod_produto )”Rentabilidade”
                      from cotacoes CO, zxt_cal_rentabilidade ZX
                      where zx.nome_cliente = (:nome) and co.cod_produto = zx.cod_produto and
                      co.data in (select max(RET_DATA) from
                      (select to_date(ZT.data_entrada)+level-1 RET_DATA
                      from zxt_cal_rentabilidade ZT
                      connect by
                      to_date(ZT.data_entrada)+level-1
                      <= last_day(to_date(ZT.data_final))
                      MINUS
                      select FI.data from feriados_internacionais FI
                      where cod_calendario = '-1316'
                      )
                      GROUP by
                      to_char(RET_DATA,'MM/YYYY')
                      )
                      order by zx.nome_do_fundo, co.data

                      como falei não sei se é a maneira mais certa de fazer, porem se tiver que trabalhar em cima da otimização da consulta creio eu que sera mais facil ja que tenho o resultado,

                      muito obrigado por enquanto…

                      #96033
                      burga
                      Participante

                        Dê uma olhada nisto, coloquei a tabela que filtra os ultimos dias uteis dos meses dentro de uma cláusula with, e utilizei esse filtro dentro da subconsulta que calcula a rentabilidade e no WHERE da consulta principal
                        Isso pra pegar somente o valor do ultimo dia útil do mês da cotação e do mês anterior, também trunquei todas as datas, pra garantir que as horas não influenciem nos filtros.

                        Como não tenho as tabelas não posso testar, então isso fica por sua conta… 😆

                        Também retirei o MAX da subconsulta, depois você repõe ele.

                        WITH t1 AS (
                        SELECT MAX(RET_DATA) ultimo_dia_util_mes
                        FROM
                        (SELECT to_date(trunc(ZT.data_entrada))+level-1 RET_DATA
                        FROM zxt_cal_rentabilidade ZT
                        CONNECT BY to_date(trunc(ZT.data_entrada))+level-1 <= last_day(to_date(trunc(ZT.data_final)))
                        MINUS
                        SELECT trunc(FI.data)
                        FROM feriados_internacionais FI
                        WHERE cod_calendario = '-1316'
                        )
                        GROUP BY TO_CHAR(RET_DATA,'MM/YYYY')
                        )
                        SELECT zx.nome_cliente,
                        zx.nome_do_fundo,
                        co.data,
                        co.valor ,
                        (SELECT (co.valor/x.valor) -1
                        FROM cotacoes x
                        WHERE TRUNC(add_months(co.data,-1),'MM') = TRUNC(x.data,'MM')
                        AND co.cod_produto = x.cod_produto
                        AND EXISTS (SELECT 1 FROM t1 WHERE TRUNC(x.data) = ultimo_dia_util_mes)
                        )"Rentabilidade"
                        FROM cotacoes CO,
                        zxt_cal_rentabilidade ZX
                        WHERE zx.nome_cliente = (:nome)
                        AND co.cod_produto = zx.cod_produto
                        AND EXISTS (SELECT 1 FROM t1 WHERE TRUNC(co.data) = ultimo_dia_util_mes)
                        ORDER BY zx.nome_do_fundo, co.data;

                        #96041
                        batofao
                        Participante

                          tambem funcionou, mais o que acontece é o seguinte, o primeiro valor ele sempre vai me retornar null, pq se o fundo começou dia 15/01/2010 ele vai tratar apenas os ultimos dias ulteis, acabei me esquecendo desse valor quebrado, no caso o primeiro valor calculado tem que ser por exemplo dia 30/01/2010(valor) / 15/01/2010(valor) no caso dia 15/01 seria minha data inicial cadastrada na tabela zxt.calc_rentabilidade, preciso aplicar a mesma regra no final, caso um fundo seja encerrado no meio do mes por exemplo

                          valeu..

                          #96053
                          burga
                          Participante

                            A data inicial do fundo é data_entrada da tabela zxt_cal_rentabilidade? Essa tabela só tem um registro ou você considera como data do primeiro valor a menor data desta tabela?

                            O NULL é somente para o primeiro valor?

                            Se sim, você pode utilizar a função NVL no x.valor, e quando x.valor = null fazer uma subquery retornando o valor da primeira data. Ex:

                            SELECT (co.valor/NVL (x.valor, ([subquery retornando valor da primeira data]))) – 1 …

                            Só lembre de colocar a subquery dentro do NVL entre parênteses…

                            #96059
                            batofao
                            Participante

                              boa noite,

                              sim essa data_entrada é a data inicial de quando um fundo começou ou de quando um cliente o adquiriu, só o primeiro valor é null, pq até agora eu trato apenas os últimos dias ulteis do mes, só para você entender um pouco mais faço uma espécie de automação de relatório, então esses dados são exportados para um excel onde uma pivot table ira tratar os mesmos, então mesmo que eu tenha mais registros na zxt_calc_rentabilidade depois de exportados os mesmos serão tratados….

                              na zxt_cal_rentabilidade eu tenho uma data_entrada e uma data_final onde é nesse periodo que eu vou fazer o calculo dos valores;

                              não entendi muito bem seu select que você enviou, que entendi tenho que faze isso:

                              WITH t1 AS (
                              SELECT MAX(RET_DATA) ultimo_dia_util_mes
                              FROM
                              (SELECT to_date(trunc(ZT.data_entrada))+level-1 RET_DATA
                              FROM zxt_cal_rentabilidade ZT
                              CONNECT BY to_date(trunc(ZT.data_entrada))+level-1 <= last_day(to_date(trunc(ZT.data_final)))
                              MINUS
                              SELECT trunc(FI.data)
                              FROM feriados_internacionais FI
                              WHERE cod_calendario = '-1316'
                              )
                              GROUP BY TO_CHAR(RET_DATA,'MM/YYYY')
                              )
                              SELECT zx.nome_cliente,
                              zx.nome_do_fundo,
                              co.data,
                              co.valor ,
                              (SELECT (co.valor/NVL (x.valor, (SELECT VALOR FROM COTACOES CO, ZXT_CAL_RENTABILIDADE ZT
                              WHERE co.cod_produto = ZT.cod_produto AND co.data = zt.data_entrada ))) – 1
                              FROM cotacoes x
                              WHERE TRUNC(add_months(co.data,-1),'MM') = TRUNC(x.data,'MM')
                              AND co.cod_produto = x.cod_produto
                              AND EXISTS (SELECT 1 FROM t1 WHERE TRUNC(x.data) = ultimo_dia_util_mes )
                              )"Rentabilidade"
                              FROM cotacoes CO, zxt_cal_rentabilidade ZX
                              WHERE zx.nome_cliente = (:nome)
                              AND co.cod_produto = zx.cod_produto
                              AND EXISTS (SELECT 1 FROM t1 WHERE TRUNC(co.data) = ultimo_dia_util_mes )
                              ORDER BY zx.nome_do_fundo, co.data;

                              porem o primeiro valor ainda é null

                              #96063
                              batofao
                              Participante

                                na verdade para retornar o valor eu só preciso disso:

                                SELECT VALOR FROM COTACOES CO, ZXT_CAL_RENTABILIDADE ZT
                                WHERE co.cod_produto = ZT.cod_produto AND co.data = zt.data_entrada

                                tentei ler um pouco sobre o nvl, mas parece que nossa sintaxe esta correta, estou rodando a consulta porem continuo com o valor null no primeiro campo…

                                #96080
                                burga
                                Participante

                                  Tenta assim:

                                  WITH t1 AS (
                                  SELECT MAX(RET_DATA) ultimo_dia_util_mes
                                  FROM
                                  (SELECT to_date(trunc(ZT.data_entrada))+level-1 RET_DATA
                                  FROM zxt_cal_rentabilidade ZT
                                  CONNECT BY to_date(trunc(ZT.data_entrada))+level-1 <= last_day(to_date(trunc(ZT.data_final)))
                                  MINUS
                                  SELECT trunc(FI.data)
                                  FROM feriados_internacionais FI
                                  WHERE cod_calendario = '-1316'
                                  )
                                  GROUP BY TO_CHAR(RET_DATA,'MM/YYYY')
                                  )
                                  SELECT zx.nome_cliente,
                                  zx.nome_do_fundo,
                                  co.data,
                                  co.valor ,
                                  NVL((SELECT (co.valor/x.valor) -1
                                  FROM cotacoes x
                                  WHERE TRUNC(add_months(co.data,-1),'MM') = TRUNC(x.data,'MM')
                                  AND co.cod_produto = x.cod_produto
                                  AND EXISTS (SELECT 1 FROM t1 WHERE TRUNC(x.data) = ultimo_dia_util_mes)
                                  ), ((co.valor/(SELECT co1.VALOR
                                  FROM COTACOES CO1,
                                  ZXT_CAL_RENTABILIDADE ZT
                                  WHERE co1.cod_produto = ZT.cod_produto
                                  AND co.cod_produto = co1.cod_produto
                                  AND co1.data = zt.data_entrada))-1)) "Rentabilidade"
                                  FROM cotacoes CO,
                                  zxt_cal_rentabilidade ZX
                                  WHERE zx.nome_cliente = (:nome)
                                  AND co.cod_produto = zx.cod_produto
                                  AND EXISTS (SELECT 1 FROM t1 WHERE TRUNC(co.data) = ultimo_dia_util_mes)
                                  ORDER BY zx.nome_do_fundo, co.data;

                                Visualizando 15 posts - 1 até 15 (de 16 do total)
                                • Você deve fazer login para responder a este tópico.
                                plugins premium WordPress