• 学习元平台最近来访的去重处理

    普通类
    • 支持
    • 批判
    • 提问
    • 解释
    • 补充
    • 删除
    • 问题:

    读取数据库的最近来访好友列表时,由于xiaojing这个用户在不同的时间段访问了我四次,那么数据库就把这四条记录都读出来了

    怎么能进行去重处理,只显示名称不同的最近来访者呢?

    (说明: 此表为user_visitresource_log 表,resourceType=5代表访问的是个人空间,userId是来访者的id,resourceId是被访者的id,那么我要查询我空间的最近来访者的基本限定条件是resourceType=5 and userId!=resourceId  and resourceId=67000 )

    • one:group by
    我们很容易的就想到了用group by 来分组不就解决了?
     
    select  *  from  user_visitresource_log  where  resourceType=5 and userId!=resourceId  and resourceId=67000  group by  userId 
     
    问题:group by 会默认的按表的时间先后顺序读取记录进行分组。group by 后得到的记录不是最新来访的记录,一旦读出了这个记录后就不会再变化。所以不可以。
     
    • two:在group by 之前排序
    那我们在group by  之前先排序不就行了?
    即 
    select  *  from  user_visitresource_log  where  resourceType=5 and userId!=resourceId  and resourceId=67000  order by visitTime desc  group by  userId 
     
    问题:语法问题,order by 必须在group by 后面。所以也不可以。
     
    • three:采用自查询
    能不能采用自查询的方式来实现?用 user_visitresource_log uv1,user_visitresource_log uv2来实现,用uv2来限定条件,uv1排序来实现。
    代码如下:
     
    select  uv1.id, uv1.userId,uv1.resourceType,uv1.resourceId,uv1.visitTime from  user_visitresource_log  uv1,user_visitresource_log  uv2  where  uv1.id=uv2.id and uv2.resourceType=5 and  uv2.userId!=uv2.resourceId  and  uv2.resourceId=67000  order by uv2.visitTime desc  group by  uv1.resourceId 
     
    即先用uv2进行order by  visitTime desc的排序,再用uv1表进行 group by resourceId,但很遗憾,这也是不可以的。
     
    • four:采用where...in
    然后想到采用 where......in 的方式可能可以实现
     
    select  * from  user_visitresource_log where  id in
    (select  id  from  user_visitresource_log  where  resourceType=5 and  userId!=resourceId and  resourceId=67000 order by  visitTime desc ) group by  userId
     
    用这种方法可以实现先order by  visitTime desc,再进行 group by resourceId的排序了。貌似是可以了。但是这种方法也是不可以的。因为where......in 在读取记录的时候也是按照id的先后顺序来读取的,这样还是得不到最新访问空间的记录。其效果和group by 差不多。
     
    • five:采用group by 配合聚合函数
    然后想到group by 一般是需要配合聚合函数来使用的。比如sum() max() min()等等。
    用这种方法试了一下
    select  *,MAX(visitTime) from user_visitresource_log where  resourceType=5 and  userId!=resourceId and   resourceId=67000 group by userId 
     
    通过这种方法我们得到了自己想要的结果,但是也出现了我们不想要的结果。
    虽然sql语句能查询出来了,但是hql语句是面向对象的,所以还是不可以。
     
    • six:采用distinct
    然后突然想到使用distinct不就可以了,把相同的都排除出去。貌似是可以的,但还是行不通。因为每条记录都是不一样的,至少每条的id和visitTime是不一样的。如果直接用 select distinct userId ...则只能取出不同的userId来。实现不了我们的目的。
     
    • seven:采用子查询
    最后采用子查询的方式,实现了查询功能。
    代码:
    select * from ( select * from user_visitresource_log where resourceType=5 and  and  userId!=resourceId and   resourceId=67000  order by visitTime desc ) as vu group by  userId   order by visitTime desc
     
    这样就可以查询出最近访问我空间的来访者了。结果是完全符合。但是,hql不支持from子查询。所以如果从这个sql语句转化为hql语句的话,还是不可以。
     
    到现在,从sql语法里面依然没有找到更好的解决办法。如果使用sql语法,其实这种查询用 group by配合聚合函数 或者使用子查询很容易就实现了我们想要的功能。但是这两种方法对hql并不感冒。