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

Responder a