Pois é, acho que a defiição está mais para periodos mesmo, ai o overlap
falha pro que eu preciso...
Mas tb não tem problema... consegui resolver usando o intersect e o
generate_series de uma forma bem limpa e com uma performance boa...
Estou postando na lista pois pode ser de serventia para o pessoal... eu
apliquei a teoria de conjuntos e criei 2 conjuntos com as datas
serializadas e depois fiz as interseçoes entre eles...
ficou um overlap inclusivo... segue:
CREATE OR REPLACE FUNCTION sobreposicao_data_inclusivo(date, date, date,
date)
RETURNS bool AS
$BODY$
DECLARE
data11 alias for $1;
data12 alias for $2;
data21 alias for $3;
data22 alias for $4;
qtd_registros_intersecao int;
BEGIN
select into qtd_registros_intersecao
count(*) from
(
(select data11 + s.a as dates
from generate_series(0,data12 - data11) as s(a))
INTERSECT
(select data21 + s.a as dates
from generate_series(0,data22 - data21) as s(a))
) as intersecao;
if qtd_registros_intersecao > 0 then
return true;
else
return false;
end if;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
Abs,
Marcelo Magno
On Tue, 2007-07-10 at 17:48 -0300, Osvaldo Rosario Kussama wrote:
> Marcelo Magno escreveu:
> > Oswaldo, acho que nao estou pescando algum feature desse overlaps...
> >
> > nessa query abaixo, pra mim existe uma sobreposicao, que seria
> > justamente o dia 01/03 mas ele me retorna falso... tem alguma
> > particularidade que não esta escrita no manual ?
> >
> > select
> > (to_date('01/03/2008','DD/MM/YYYY'),to_date('31/05/2008','DD/MM/YYYY'))
> > overlaps
> > (to_date('01/01/2008','DD/MM/YYYY'),to_date('01/03/2008','DD/MM/YYYY'))
> >
> > Fico grato se puder me ajudar,
> >
> > Abracos,
> > Marcelo Magno
> >
> > On Tue, 2007-07-10 at 09:30 -0300, Marcelo Magno wrote:
> >> muitissimo obrigado oswaldo...
> >>
> >> Abs,
> >> Marcelo Magno
> >>
> >> On Mon, 2007-07-09 at 17:18 -0300, Osvaldo Rosario Kussama wrote:
> >>> Marcelo Magno escreveu:
> >>> > Boa tarde pessoal,
> >>> >
> >>> > Eu estou tendo alguma dificuldade para lidar com conjuntos de datas. No
> >>> > meu caso, eu tenho em cada tupla da tabela a informacao de data inicial
> >>> > e data final. Quando um usuario entra um periodo (digamos de hoje ate
> >>> > semana que vem) eu preciso fazer uma especie de intersessao dos dois
> >>> > conjuntos de datas e caso exista essa intersessao, retornar essa tupla.
> >>> >
> >>> > Eu estava usando uma script em pl-sql que fazia um loop dia a dia, mas
> >>> > por motivos de lentidao, estou procurando outra metodologia...
> >>> >
> >>> > Eu até consigo gerar os periodos usando a funcao generate_series, mas
> >>> > parei por ai... nao estou conseguindo progredir... Existe alguma forma
> >>> > de comparar conjuntos no where ? queria comparar o periodo entre data
> >>> > inicial e final da tupla, como os periodos entrado pelo usuario.
> >>> >
> >>> > Em outras ocasioes eu já usei de comparacoes de datas para achar as
> >>> > intersessoes, mas essa metodologia é dificil de debugar e estou
> >>> > querendo
> >>> > fugir dela no momento.
> >>> >
> >>> > Se alguem puder me dar uma luz diferente, fico grato.
> >>> >
> >>>
> >>>
> >>> Veja o operador OVERLAPS em:
> >>> http://www.postgresql.org/docs/8.2/interactive/functions-datetime.html
> >>>
>
>
> É a definição do operador OVERLAPS (como ele considera os limites dos
> intervalos). Veja os exemplos abaixo:
>
> bdteste=# SELECT * FROM t_dates;
> id | sd1 | ed1 | sd2 | ed2
> ----+------------+------------+------------+------------
> 1 | 08/07/2007 | 08/07/2007 | 08/07/2007 | 08/07/2007
> 2 | 07/07/2007 | 08/07/2007 | 08/07/2007 | 08/07/2007
> 3 | 08/07/2007 | 08/07/2007 | 08/07/2007 | 09/07/2007
> 4 | 07/07/2007 | 08/07/2007 | 08/07/2007 | 09/07/2007
> 5 | 08/07/2007 | 08/07/2007 | 07/07/2007 | 08/07/2007
> (5 registros)
>
> bdteste=# SELECT *, (sd1,ed1) OVERLAPS (sd2,ed2) FROM t_dates;
> id | sd1 | ed1 | sd2 | ed2 | overlaps
> ----+------------+------------+------------+------------+----------
> 1 | 08/07/2007 | 08/07/2007 | 08/07/2007 | 08/07/2007 | t
> 2 | 07/07/2007 | 08/07/2007 | 08/07/2007 | 08/07/2007 | f
> 3 | 08/07/2007 | 08/07/2007 | 08/07/2007 | 09/07/2007 | t
> 4 | 07/07/2007 | 08/07/2007 | 08/07/2007 | 09/07/2007 | f
> 5 | 08/07/2007 | 08/07/2007 | 07/07/2007 | 08/07/2007 | f
> (5 registros)
>
> Talvez o resultado desejado seja alcançado com o operador BETWEEN:
>
> bdteste=# SELECT *, (sd1,ed1) OVERLAPS (sd2,ed2), ((sd1 BETWEEN sd2 AND
> ed2) OR (ed1 BETWEEN sd2 AND ed2)) AS x FROM t_dates;
> id | sd1 | ed1 | sd2 | ed2 | overlaps | x
> ----+------------+------------+------------+------------+----------+----------
> 1 | 08/07/2007 | 08/07/2007 | 08/07/2007 | 08/07/2007 | t | t
> 2 | 07/07/2007 | 08/07/2007 | 08/07/2007 | 08/07/2007 | f | t
> 3 | 08/07/2007 | 08/07/2007 | 08/07/2007 | 09/07/2007 | t | t
> 4 | 07/07/2007 | 08/07/2007 | 08/07/2007 | 09/07/2007 | f | t
> 5 | 08/07/2007 | 08/07/2007 | 07/07/2007 | 08/07/2007 | f | t
> (5 registros)
>
> Se for este o caso você pode, para evitar a repetição do segundo
> período, fazer uma função como:
>
> CREATE OR REPLACE FUNCTION
> overlaps_inclusive(date, date, date, date) RETURNS bool AS
> $$
> SELECT (($1 BETWEEN $3 AND $4) OR ($2 BETWEEN $3 AND $4));
> $$ LANGUAGE SQL;
> _______________________________________________
> pgbr-geral mailing list
> [email protected]
> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral