- Este tópico contém 15 respostas, 3 vozes e foi atualizado pela última vez 14 anos, 3 meses atrás por batofao.
-
AutorPosts
-
9 de setembro de 2010 às 4:55 pm #95997batofaoParticipante
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;9 de setembro de 2010 às 5:31 pm #96003burgaParticipanteVamos 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;9 de setembro de 2010 às 5:39 pm #96004batofaoParticipanteisso mesmo,
muito obrigado… 😀
10 de setembro de 2010 às 6:44 pm #96027batofaoParticipanteme 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
10 de setembro de 2010 às 7:08 pm #96028jspaulonciParticipanteTô falando !!!! Burga vc é nosso guru de sql, e deixa de modestia heim.
kkkkkkkkkkkkk
abraços
10 de setembro de 2010 às 9:40 pm #96029batofaoParticipantenão sei se consegui explicar bem no topico acima.
obg
10 de setembro de 2010 às 10:17 pm #96030burgaParticipanteHummm, 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… 😳10 de setembro de 2010 às 11:00 pm #96031batofaoParticipantefiz 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..
10 de setembro de 2010 às 11:52 pm #96032batofaoParticipanteconsegui,
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.datacomo 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…
11 de setembro de 2010 às 12:31 am #96033burgaParticipanteDê 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;13 de setembro de 2010 às 3:29 pm #96041batofaoParticipantetambem 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..
13 de setembro de 2010 às 8:44 pm #96053burgaParticipanteA 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…
14 de setembro de 2010 às 6:03 am #96059batofaoParticipanteboa 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
14 de setembro de 2010 às 7:56 pm #96063batofaoParticipantena 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_entradatentei 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…
15 de setembro de 2010 às 2:39 am #96080burgaParticipanteTenta 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; -
AutorPosts
- Você deve fazer login para responder a este tópico.