请教一个sql(按某个字段分组然后从每组取出最大的一条纪录)?
比如表  data_table
字段有:id、name、address、tel、update
         1   n1    a1       s1   20070801
         2   n2    a1       s2   20070302
         3   n3    a2       s3   20070501
         4   n3    a2       s3   20070301
我想得到的数据是  按照 address 分组 然后取出每组中update最大的那几条纪录。结果应该是这两条纪录:
         1   n1    a1       s1   20070801
         3   n3    a2       s3   20070501请问怎么写sql?谢谢

解决方案 »

  1.   

    select id, name, address, tel, update 
      from (
            select id, name, address, tel, update,
                   row_number() over(partition by address order by update desc) rn
              from data_table
           ) 
     where rn = 1
      

  2.   

    SELECT * FROM A,(SELECT A.address,MAX(A.update) FROM A GROUP BY A.address) C
    WHERE A.address = C.address
    AND A.update = C.update
      

  3.   

    SQL> select *
      2    from (
      3          select tt.*,
      4                 row_number() over(partition by tt.address order by tt.update1 desc) rn
      5            from (
      6                   select 1 as id,'n1' as name,'a1' as address,'s1' as tel,'20070801' as update1 from dual
      7                   union all
      8                   select 2 as id,'n2' as name,'a1' as address,'s2' as tel,'20070302' as update1 from dual
      9                   union all
     10                   select 3 as id,'n3' as name,'a2' as address,'s3' as tel,'20070501' as update1 from dual
     11                   union all
     12                   select 4 as id,'n3' as name,'a2' as address,'s3' as tel,'20070301' as update1 from dual
     13                 )tt
     14         )zz
     15   where zz.rn = 1;        ID NAME ADDRESS TEL UPDATE1          RN
    ---------- ---- ------- --- -------- ----------
             1 n1   a1      s1  20070801          1
             3 n3   a2      s3  20070501          1
      

  4.   

    谢谢各位,我试一下。
    -------------------------------------
    回复人:kimi_deng() SELECT * FROM A,(SELECT A.address,MAX(A.update) FROM A GROUP BY A.address) C
    WHERE A.address = C.address
    AND A.update = C.update首先谢谢您的回答,但是您的sql有点不严谨,就是说address和update的值并不是主键,不能标识唯一的纪录,所有查出的数据不准确。
      

  5.   

    select * 
    from data_table t
    where not exists(select 1 
                       from data_table 
                          where address=t.address 
                                and update>t.update)
      

  6.   

    回复人:kimi_deng() SELECT * FROM A,(SELECT A.address,MAX(A.update) FROM A GROUP BY A.address) C
    WHERE A.address = C.address
    AND A.update = C.update这里存在一点问题,select选择的应该只有A(data_table)表中4个字段,子查询的表C中只是包括2个字段,如果用*就会增加查询的字段数,不过我觉得他的思路很好!做法很简单
      

  7.   

    kimi_deng() 的做法,的确不严谨。
    只是没有考虑到,按照address分组以后,假如update有重复的值,怎么再区分呢?这个就需要楼主把表的结构,解释一番。
      

  8.   

    回复人:Croatia(Croatia) kimi_deng() 的做法,的确不严谨。
    只是没有考虑到,按照address分组以后,假如update有重复的值,怎么再区分呢?这个就需要楼主把表的结构,解释一番。
    ----------------------------表的结构就是id是主键,最后根据分组取出update最大的纪录。应该是adress和update的值是可以重复的,如果这几条纪录的这两个字段是相同的(有这种可能性),那么这个sql语句无异于select * from data_table;
    只是没有考虑到,按照address分组以后,假如update有重复的值,怎么再区分呢?
    --------
    不知这种区分的办法需要知道表的具体怎样的结构呢?
      

  9.   

    不好意思,现在才看到。你已经结贴了。
    Q:只是没有考虑到,按照address分组以后,假如update有重复的值,怎么再区分呢?
    --------
    A1:不知这种区分的办法需要知道表的具体怎样的结构呢?
    --------
    A1:这个就需要看你的需求是什么了。
      

  10.   

    来完了,不过1楼得20分是对的.row_number()   over(partition   by   address   order   by   update   desc) 就是专门用来回答楼主的问题的分析函数.
    不过回复人:kimi_deng()   SELECT   *   FROM   A,(SELECT   A.address,MAX(A.update)   FROM   A   GROUP   BY   A.address)   C 
    WHERE   A.address   =   C.address 
    AND   A.update   =   C.update 是在不用分析函数时很好的思路. 细节方面完善一下就行了.
      

  11.   

    select   id,   name,   address,   tel,   update   
        from   ( 
                    select   id,   name,   address,   tel,   update, 
                                  row_number()   over(partition   by   address   order   by   update   desc)   rn 
                        from   data_table 
                  )t1   
      where   rn   =   1