Como trazer conjuntos de resultados usando Criteria...?

Tenho uma situação que realmente não sei como resolver… tem a ver com conjuntos.

Considerando os seguintes registros:descrição data_inicial data_final linha1 01/01/2001 01/05/2005 linha2 01/01/2002 01/05/2005 linha3 01/01/2004 01/05/2005E desejo todos os registros que estejam DENTRO do período de 01/01/2003 até 31/05/2003

deveriam retornar as linha1 e linha2

linha3 não deve retornar, pois não está DENTRO do intervalo solicitado

COMO fazer isso com Hibernate?

Pelo que entendi a sua pesquisa seria assim:
data_inicial: 01/01/2003
data_final: 31/05/2003

Então, basta testar se a sua data_inicial é menor igual a data_final. Se for, a pesquisa vai retornar todas as datas iniciais que estiverem nesse intervalo. A data_inicial que for maior que a data_final não será retornada.

A consulta poderia ser assim:

O Restrictions.le(), é o mesmo que a condição de <=

[quote=romarcio]Pelo que entendi a sua pesquisa seria assim:
data_inicial: 01/01/2003
data_final: 31/05/2003

Então, basta testar se a sua data_inicial é menor igual a data_final. Se for, a pesquisa vai retornar todas as datas iniciais que estiverem nesse intervalo. A data_inicial que for maior que a data_final não será retornada.

A consulta poderia ser assim:

O Restrictions.le(), é o mesmo que a condição de <=[/quote]

Não funciona, pois, pexemplo, se eu passar o período de 2015 até 2016 esses registros não podem retornar e, segundo sua regra, eles retornariam.

Eu não entendi o que você quis dizer.
Eu coloquei o código diferente do que eu falei, o certo pelo que eu disse seria assim:

List&lt;SuaClasse&gt; list = getSession().createCriteria(SuaClasse.class).add(Restrictions.le(&quot;data_Inicial&quot;, dataFinal)).list(); Teria que testar a data inical <= data final

Queres todos os registos que se encontrem totalmente dentro do intervalo ou que apanhem qualquer parte do intervalo.

No teu exemplo, um registo de 01/01/2002 a 31/03/2003 deve ser devolvido?

List&lt;SuaClasse&gt; list = getSession().createCriteria(SuaClasse.class)
.add(Restrictions.le(&quot;data_Inicial&quot;, dataFinal))
.add(Restrictions.ge(&quot;data_Final&quot;, dataInicial))
.list(); 

ge() é o mesmo que >=

Assim teriamos:
Data inicial <= data final
and
Data final >= data inicial

[quote=romarcio]Assim teriamos:
Data inicial <= data final
and
Data final >= data inicial[/quote]

exato! fiz uns testes aqui e cheguei ao mesmo where seu… creio q isso resolve! obrigado!

Se queres apenas os resultados que se encontram totalmente no intervalo, resolve.
Se queres todos os resultados que se encontrem também parcialmente no intervalo, não resolve.

[quote=pmlm]Se queres apenas os resultados que se encontram totalmente no intervalo, resolve.
Se queres todos os resultados que se encontrem também parcialmente no intervalo, não resolve.[/quote]

No meu caso preciso dos resultados que se encontrem também parcialmente. Como poderia resolver isso?

Olha só, criei o seguinte caso de teste:

id 	dtInicio	dtFim
1	2001-01-01	2002-01-01
2	2001-01-01	2002-05-31
3	2001-01-01	2003-01-01
4	2002-01-01	2003-01-01
5	2002-01-01	2004-01-01 
6	2002-01-01 	2005-01-01 
7	2003-01-01	2003-05-31 *
8	2003-01-01	2005-01-01
9	2004-01-01	2004-05-31
10	2004-01-01	2005-01-01
11	2005-01-01	2005-05-31
12	2005-01-01	2006-01-01
13	2006-01-01 	2006-05-31	

Para esse intervalo: 2003-01-01 a 2003-05-31
O único aceito seria o id=7

Então primeiro usamos a consulta com as seguintes restrições:
dtInicio <= dtFim And dtFim >= dtInicio

.add(Restrictions.le(&quot;dtInicio&quot;, fim)) .add(Restrictions.ge(&quot;dtFim&quot;, inicio))
E teremos todos esses resultados:

id=3, dtInicio=2001-01-01, dtFim=2003-01-01 id=4, dtInicio=2002-01-01, dtFim=2003-01-01 id=5, dtInicio=2002-01-01, dtFim=2004-01-01 id=6, dtInicio=2002-01-01, dtFim=2005-01-01 id=7, dtInicio=2003-01-01, dtFim=2003-05-31 * id=8, dtInicio=2003-01-01, dtFim=2005-01-01

Então uso mais uma restrição:
dtFim <= dtFim -> Assim elimina todas as datas que tinham a dtFim maior que o parâmetro dtFim

E o resultado passa a ser:

id=3, dtInicio=2001-01-01, dtFim=2003-01-01 id=4, dtInicio=2002-01-01, dtFim=2003-01-01 id=7, dtInicio=2003-01-01, dtFim=2003-05-31 *

Para finalizar, a ultima restrição:
dtInicio >= dtIncio -> Assim eliminamos todas as datas que estariam em um intervalo com dtInicio menor que o parâmetro de dtInicio

E o resultado final:

A consulta então seria essa:

List&lt;SuaClasse&gt; list = getSession().createCriteria(SuaClasse.class) .add(Restrictions.le("data_Inicial", dataFinal)) .add(Restrictions.ge("data_Final", dataInicial)) .add(Restrictions.le("data_Final", dataFinal)) .add(Restrictions.ge("data_Inicial", dataInicial)) .list();

OBS: Cria um caso de teste maior e com intervalos de datas mais bem distribuídos e faz um teste.

Precisas de ver os registos de três situações:

  • Os que começam antes da data de inicio do intervalo e terminam depois dessa data de inicio
  • Os que começam antes da data de fim do intervalo e terminam depois dessa data de fim
  • Os que começam depois da data de inicio do intervalo e terminam antes da data de fim

Com estes três casos cobres todas as situações.

[quote=pmlm]Precisas de ver os registos de três situações:

  • Os que começam antes da data de inicio do intervalo e terminam depois dessa data de inicio
  • Os que começam antes da data de fim do intervalo e terminam depois dessa data de fim
  • Os que começam depois da data de inicio do intervalo e terminam antes da data de fim

Com estes três casos cobres todas as situações.[/quote]

  • E os que começaram antes da data de inicio e terminaram na própria data de inicio, fazem parte do intervalo?
    Por exemplo, intervalo entre: 2003-01-01 a 2003-05-31. O intervalo: 2001-01-01 2003-01-01 é válido ou não?

Qualquer antes ou depois das minhas regras devem ler-se como <= ou >=
:slight_smile:

[quote=pmlm]Qualquer antes ou depois das minhas regras devem ler-se como <= ou >=
:-)[/quote]

Então essa consulta que eu tinha postado anteriormente está correta:

List<SuaClasse> list = getSession().createCriteria(SuaClasse.class)
.add(Restrictions.le("data_Inicial", dataFinal))
.add(Restrictions.ge("data_Final", dataInicial))
.list(); 

Ela abrange todas as regras, veja:

id 	dtInicio	dtFim
1	2001-01-01	2002-01-01 
2	2001-01-01	2002-05-31
3	2001-01-01	2003-01-01 A 
4	2002-01-01	2003-01-01 A 
5	2002-01-01	2004-01-01 A - B 
6	2002-01-01 	2005-01-01 A - B
7	2003-01-01	2003-05-31 D 
8	2003-01-01	2005-01-01 B 
9	2004-01-01	2004-05-31
10	2004-01-01	2005-01-01
11	2005-01-01	2005-05-31
12	2005-01-01	2006-01-01
13	2006-01-01 	2006-05-31	
14	2003-02-01	2003-03-01 C

Legenda:
A Os que começam antes da data de inicio do intervalo e terminam depois dessa data de inicio
B Os que começam antes da data de fim do intervalo e terminam depois dessa data de fim
C Os que começam depois da data de inicio do intervalo e terminam antes da data de fim
D O próprio intervalo

Aparentemente sim… Isso funciona como um OR?

Sim. Seria o mesmo que um select desse tipo:

    select
       ID,
       DATA_FIM,
       DATA_INICIO
    from
        CADASTROS 
    where
        DATA_INICIO<= '2003-05-31'  and DATA_FIM>='2003-01-01'