表结构
serial_no  user_id     O_datetime             NOTE
1           F001      2012-05-04  14:10
2           F001      2012-05-06   10:00   
3           F001      2012-05-04  12:10
4           F004      2012-05-02  10:15
5           F001      2012-05-04   14:10
6           D002      2012-05-01   09:00
7           F001      2012-05-05   10:00   
8           F001      2012-05-06   10:00 
9           F001      2012-05-01   09:00serial_no是自增列
我要得到user_id分组o_datetime是最大的的一条记录
我目前使用的是
select * from tab1 as t where serial_no=(select top 1 serial_no from tab1 where t.user_id=user_id order by o_datetime desc)
查询速度效果很差
如果使用max(o_datetime)会出现二条记录,因为有时间是相同的

解决方案 »

  1.   

    if object_id('[TB]') is not null drop table [TB]
    go
    create table [TB] (serial_no int,user_id nvarchar(8),O_datetime datetime,NOTE sql_variant)
    insert into [TB]
    select 1,'F001','2012-05-04 14:10',null union all
    select 2,'F001','2012-05-06 10:00',null union all
    select 3,'F001','2012-05-04 12:10',null union all
    select 4,'F004','2012-05-02 10:15',null union all
    select 5,'F001','2012-05-04 14:10',null union all
    select 6,'D002','2012-05-01 09:00',null union all
    select 7,'F001','2012-05-05 10:00',null union all
    select 8,'F001','2012-05-06 10:00',null union all
    select 9,'F001','2012-05-01 09:00',nullselect * from [TB]
    select distinct B.user_id,B.O_datetime
    from TB a
    cross apply(select top 1 user_id,O_datetime 
    from TB 
    where a.user_id = user_id order by O_datetime desc)B
      

  2.   

    select top 1 user_id,O_datetime 
                from TB 
                where a.user_id = user_id order by O_datetime desc
    这种查询方式效果很差
    并且 还有一个NOTE列,这儿存储 的一些字符串信息,所以这二列是不相同的
      

  3.   


    select distinct B.user_id,B.O_datetime
    from TB a
    cross apply(select top 1 user_id,O_datetime 
                from TB 
                where a.user_id = user_id order by O_datetime desc)B我还有一个NOTE,这儿存储 的是字符,不同的,所以使用distinct没有任何意义
      

  4.   


    LZ贴下执行计划看看到底是什么地方慢了,Ctrl+L
    2005版本往上推荐使用cross apply来处理分组top的问题,之前也实际测试过,应该算较为优化的方法了。
      

  5.   

    用你这种写法,哪我还有一列note咋办呢
      

  6.   

    大哥大姐些,主要是哪相时间传过来的时候只精确到秒,很容易相同,并且有可能最大的时间在前面,所以使用max(serila_no)不行了,
      

  7.   

    select top 1 user_id,O_datetime ,note
    from TB 
    where user_id ='AAA'
    order by O_datetime  desc
    LZ 看看这个语句的执行计划,看看走没走索引。听起来感觉你这个慢的问题,貌似是没走索引闹的。
    如果是数据量很大的话,建议使用分区表,分区索引的方式
      

  8.   


    聚集索引扫描? 
    scan的话性能不高。LZ尝试下将上述要选定的3个列 user_id,O_datetime ,note 建立一个覆盖索引。
    这样应该可以使用到 index seek ,效率应该会有所提高。100多万的数据量还好啊。之前top1 的语句用了多长时间呢?应该不至于会慢的厉害的。
      

  9.   

    你想得到 o_datetime是最大的的一条记录
    可是 “如果使用max(o_datetime)会出现二条记录,因为有时间是相同的”
    “并且 还有一个NOTE列,这儿存储 的一些字符串信息,所以这二列是不相同的”
    这根本就是矛盾的吗。比如 同一个 o_datetime 值 有多条记录, 怎么区分要哪个?请给出规则啊
      

  10.   

    你的聚集索引建在 serial_no 上面?
     user_id 和 O_datetime  这两列上有没有索引?
    在这两个上面分别建立非聚集索引 然后再试试
      

  11.   


    select *
    from tb a
    where not exists (select 1 from tb b
        where b.user_id=a.user_id and b.O_datetime>a.O_datetime)