下面是我的HQL语句,from ActivateTask at3 
where not exists (
from ActivateTask at4 
where at4.terminal = at3.terminal 
and at4.activateDate > at3.activateDate
)and at3.status=0 
and at3.terminal in (
select at2.terminal 
from ActivateTask at2 
where not exists (
from ActivateTask at1 
where at1.terminal = at2.terminal 
and at1.activateDate > at2.activateDate

and (at2.status=0 or at2.status=3)
)上面的table均为同一个表,该表的结构如下:
ID | DATE | TERMINAL | STATE
查询要求是:
 按照TERMINAL 字段进行分组,找到每组中
DATE最大
并且STATE=0
并且该组中DATE最大的记录的STATE必须等于0或3。
(由于每组中STATE=0并且DATE最大的记录可能不是该组中DATE最大的记录,因此要对该组中DATE最大的记录的STATE进行判断,如果等于0或3,再取该组中STATE=0并且DATE最大的记录,否则 该组就过滤掉,相当于没有记录可取)
例如:表
ID | DATE      | TERMINAL | STATE
0  | 20100506| 00001       | 0
1  | 20100606| 00001       | 1
2  | 20100706| 00001       | 0
3  | 20100806| 00001       | 3
4  | 20100506| 00002       | 0
5  | 20100606| 00002       | 0
6  | 20100706| 00002       | 1
7  | 20100506| 00003       | 0
8  | 20100606| 00003       | 0
查询结果应当为:
ID | DATE      | TERMINAL | STATE
2  | 20100706| 00001       | 0
8  | 20100606| 00003       | 0
注意:必须用HQL,如果用SQL,我自己也会避免使用in exists等关键字提升性能,关键是现在必须用HQL,HQL中好像不支持from(select...), othertable的形式进行嵌套查询,所以分组取最大值很难实现,因此,我通过上面的HQL实现了要求,可是我怕性能不能保障,请高手看看有没有性能提升的空间,或者帮忙重新写一条HQL语句,只要能达成上面功能的又比我的HQL性能好的。

解决方案 »

  1.   

    这............
    select max(日期) from group by 组  where =0 or =3select * from a t  where 日期=(select max(日期) from a o group by 组  where ( =0 or =3) and t.组=o.组)
    不知道行不行.
      

  2.   

    查询出每组  (日期 =MAX(日期) and ( state =0 or state =3 )  感觉没这么简单, 回家试试.. 并且STATE=0
    并且该组中DATE最大的记录的STATE必须等于0或3。
    (由于每组中STATE=0并且DATE最大的记录可能不是该组中DATE最大的记录,因此要对该组中DATE最大的记录的STATE进行判断,如果等于0或3,再取该组中STATE=0并且DATE最大的记录,否则 该组就过滤掉,相当于没有记录可取)  这句意思是 最后 state =0 呢 还是 state =0 or 3 呢 
      

  3.   

    对于每一组而言 先找出 date = max(date) 判断 state = 0 or 3 是否成立  在这个条件成立的前提下找state = 0 and date = max(date)的如果那个前提条件不成立,那么该组就不用找了最后结果肯定是state=0的 也就是说,最后的结果,不一定每组都会查到值 有可能值查到 TERMINAL中的几个组
    看我举的那个例子
    ID | DATE | TERMINAL | STATE
    0 | 20100506| 00001 | 0
    1 | 20100606| 00001 | 1
    2 | 20100706| 00001 | 0
    3 | 20100806| 00001 | 3
    4 | 20100506| 00002 | 0
    5 | 20100606| 00002 | 0
    6 | 20100706| 00002 | 1
    7 | 20100506| 00003 | 0
    8 | 20100606| 00003 | 0
    查询结果应当为:
    ID | DATE | TERMINAL | STATE
    2 | 20100706| 00001 | 0
    8 | 20100606| 00003 | 0
      

  4.   

    select * from a t where 日期=(select max(日期) from a o group by 组 where ( =0 or =3) and t.组=o.组)
    这条SQL语句就可以啦
      

  5.   

    我在解释下那个例子
    ID | DATE | TERMINAL | STATE
    0 | 20100506| 00001 | 0
    1 | 20100606| 00001 | 1
    2 | 20100706| 00001 | 0
    3 | 20100806| 00001 | 3
    4 | 20100506| 00002 | 0
    5 | 20100606| 00002 | 0
    6 | 20100706| 00002 | 1
    7 | 20100506| 00003 | 0
    8 | 20100606| 00003 | 0
    查询结果应当为:
    ID | DATE | TERMINAL | STATE
    2 | 20100706| 00001 | 0
    8 | 20100606| 00003 | 0第一步
    首先按照TERMINAL分组 
    那么分组结果应当为,(括号中数字为记录ID)
    group1 (0,1,2,3) 该租是TERMINAL为00001的
    group2 (4,5,6) 该租是TERMINAL为00002的
    group3 (7,8) 该租是TERMINAL为00003的
    第二步
    下来按照要求对每组中DATE最大的记录进行判断,查看state是否=0 or =3,
    对于group1来说DATE最大的是ID为4的那条记录,他的STATE=3满足条件
    对于group2来说DATE最大的是ID为6的那条记录,他的STATE=1不满足条件
    对于group3来说DATE最大的是ID为8的那条记录,他的STATE=0满足条件
    这样由于group2不满足条件,那么结果应当是在group1与group3中产生
    第三步
    按照要求在group1与group3中找DATE最大并且state = 0的记录
    对于group1 DATE最大并且state = 0的记录应当是ID为2的那一条
    对于group3 DATE最大并且state = 0的记录应当是ID为8的那一条
    这样找出的最终结果应当为ID | DATE | TERMINAL | STATE
    2 | 20100706| 00001 | 0
    8 | 20100606| 00003 | 0不知道我这样说,你们能明白不,我要如何查询
    将上述三步放在同一个HQL语句里完成,最终出结果
      

  6.   

    本帖最后由 AWUSOFT 于 2010-09-07 11:02:02 编辑