前面发了两个帖子已经结贴给分,发现描述不清楚,再重新来一次:)表结构及数据如下:  name     dtime    place  word      wgt  total
--------------------------------------------------
 alice   2009-03-01  cn    math      25      15
 bob     2009-02-09  jp    english   12      0
 bob     2009-02-09  jp    eng       12      0
 bob     2009-02-09  jp    ena       12      0
 alice   2009-03-01  cn  mathu     25         15
 alice   2009-03-01  jp    mathut    47       90
 alice   2009-01-01  cn  fish      12         15现在要选择特定人的最近对应的10个数据,数据满足条件:
1、按照日期排序(越接近今天,越靠前)
2、同一个日期对应的数据,只选择2条.
3、如果同一个日期中有数据超过2条,则优先total字段大的,如果total字段相同则,选择wgt字段大的,
   如果wgt字段相同,则选择word字段长度大的,如果word长度还是一样,则选择字符串比
   较结果大的.(附注:word字段是不会重复)
4、保证查询结果中一个人每一天的数据记录不超过2条(即条件2)这语句咋写呢.....例如,如果查alice的话,那么结果应该是:
 name     dtime     place word      wgt  total
-----------------------------------------------------
alice   2009-03-01  jp mathut    47     90  (因为total中 90 最大)           \两条
alice   2009-03-01  cn mathu     25    15   (因为mathu长度比math大)  /偶数量了
alice   2009-01-01  cn fish      12    15   (因为当天只有一条)这个结果中,2009-03-01只有两条数据。但数据库表中有4条。
如果查bob的话,结果是:
 name     dtime     place word      wgt  total 
-----------------------------------------
 bob     2009-02-09  jp english   12   0 (因为english长度最大)
 bob     2009-02-09  jp eng       12   0 (因为字符串比较eng>ena)写出查询alice的语句..咋整?

解决方案 »

  1.   

    服了你了,变通一下嘛,
    SELECT a.name, a.DTime, a.WORD, A.WGT
    FROM tt1 AS a LEFT JOIN tt1 AS b ON 
    a.total<=b.total and
    a.DTime=b.DTime AND 
    a.wGT<=b.WGT AND
    LENgth(A.WORD)<=LENgth(B.WORD) And 
    A.WORD<=B.WORD 
    AND a.name=b.name
    GROUP BY a.name, a.DTime, a.WORD, A.WGT
    HAVING COUNT(B.WORD)<=2
    ORDER BY A.NAME, a.DTime DESC
      

  2.   

    加入PLACE
    SELECT a.name, a.DTime, a.WORD, A.WGT,A.PLACE
    FROM tt1 AS a LEFT JOIN tt1 AS b ON
    a.total <=b.total and
    a.DTime=b.DTime AND
    a.wGT <=b.WGT AND
    LENgth(A.WORD) <=LENgth(B.WORD) And
    A.WORD <=B.WORD
    AND a.name=b.name
    GROUP BY a.name, a.DTime, a.WORD, A.WGT,A.PLACE
    HAVING COUNT(B.WORD) <=2
    ORDER BY A.NAME, a.DTime DESC 
      

  3.   

    SELECT a.name, a.DTime, a.WORD, A.WGT,A.PLACE
    FROM tt1 AS a LEFT JOIN tt1 AS b ON
    a.total <=b.total and
    a.DTime=b.DTime AND
    a.wGT <=b.WGT AND
    LENgth(A.WORD) <=LENgth(B.WORD) And
    A.WORD <=B.WORD
    AND a.name=b.nameWHERE A.NAME='alice'GROUP BY a.name, a.DTime, a.WORD, A.WGT,A.PLACE
    HAVING COUNT(B.WORD) <=2
    ORDER BY A.NAME, a.DTime DESC 
      

  4.   

    select *
    from yourTable a
    where 2> (
        select count(*) from yourTable 
        where dtime=a.dtime 
        and (
            total>a.total 
            or (total=a.total and wgt>a.wgt)
            or (total=a.total and wgt=a.wgt and len(word)>len(a.word))
            or (total=a.total and wgt=a.wgt and len(word)=len(a.word) and word>a.word)
            )
        )
    order by dtime desc
      

  5.   

    大侠,你这个执行速度太
    蜗牛一样啊。。我刚执行了一下,在5万条数据集基础上。。
    到现在都快3分钟了。。还没执行完毕MYSQL 5.0..
      

  6.   

    上传你的MDB到www.access911.net/csdn
    只要有问题的表、查询,用WINRAR压缩
      

  7.   

    select name,dtime,place,total,wgt,word from (select (select count(word) from tt b  where a.dtime=b.dtime and  a.total<=b.total and a.wgt<=b.wgt and length(a.word)<=length(b.word) and a.word<b.word) as rank,a.* from tt a where a.name='alice') a where rank<2 
    这个应该可以,就是没有给结果排序。
      

  8.   


    万级以上,你不说,我也猜不出啊。提问也是门学问。改成 join 速度上会提高。
    select a.name,a.dtime,a.place,a.word,a.wgt,a.total 
    from yourTable a inner join yourTable b on a.name=b.name and (
    b.total>a.total 
            or (b.total=a.total and wgt>a.wgt)
            or (b.total=a.total and wgt=a.wgt and len(word)>len(a.word))
            or (b.total=a.total and wgt=a.wgt and len(word)=len(a.word) and word>=a.word)
            )
    where a.name='alice'
    group by a.name,a.dtime,a.place,a.word,a.wgt,a.total 
    having count(*)<=2
      

  9.   


    上传你所说出问题的数据,www.access911.net/csdn 
    否则恐怕没有人能帮你,
    感觉你要首先明确你要达到什么目的
      

  10.   

    已经上传啦。。result.txt...多谢大侠!!
    查一下伊辛巴耶娃就知道了
      

  11.   

    你用SQLYOG OR MYSQLDUMP 备份一下你的表,上传
      

  12.   

    上传完毕,有劳WWWWA! 改了一下字段的
    你用“伊辛巴耶娃”来检验你的语句就OK。。
      

  13.   


    delimiter //
    drop procedure if exists ret//
    create procedure ret(s_name varchar(10))
    begin
    declare a varchar(20);
    declare b int default 0;
    declare c_1 cursor for select ttime from trace where name=s_name group by ttime;
    declare exit handler for not found set b=1;
    drop table if exists temp_1;
    create table temp_1 like trace;
    open c_1;
    while(b=0) do
      fetch c_1 into a;
      insert into temp_1 (select * from trace where name=s_name and ttime=a order by total desc,wgt desc,length(word) desc,word desc limit 2);
    end while;
    close c_1;
    end//
    delimiter ;
    call ret('阿德');
    select * from temp_1 order by ttime desc limit 10;
      

  14.   

    select a.name,a.ttime,a.place,a.word,a.wgt,a.total 
    from trace a inner join trace b on a.name=b.name and (
            b.total>a.total 
            or (b.total=a.total and b.wgt>a.wgt)
            or (b.total=a.total and b.wgt=a.wgt and len(b.word)>len(a.word))
            or (b.total=a.total and b.wgt=a.wgt and len(b.word)=len(a.word) and b.word>=a.word)
            )
    where a.name='丁伟'
    group by a.name,a.ttime,a.place,a.word,a.wgt,a.total 
    having count(*)<=2结果name ttime place word wgt total
    丁伟 3/7/2009 北京市 自治区 2 2
    丁伟 3/7/2009 北京市 集团公司 2 2name ttime place word wgt total
    丁伟 3/7/2009 北京市 自治区 2 2
    丁伟 3/7/2009 北京市 集团公司 2 2
    丁先生 3/1/2009 长沙市 蹊跷 1 1
    丁先生 3/1/2009 长沙市 银行 2 1
    丁向阳 3/3/2009 北京市 旅游局 3 3
    丁向阳 3/3/2009 北京市 进行 3 3
    丁正 3/5/2009 济南市 市政府 1 1
    丁正 3/5/2009 济南市 问题 1 1
    丁玉兰 3/2/2009 商丘市 老太太 1 1
    丁玉兰 3/2/2009 商丘市 难度 1 1
    丁立新 3/4/2009 河北省 拍卖会 13 13
    丁立新 3/4/2009 河北省 集团 25 13
    丁继坤 2/26/2009 韩城市 下乡 4 2
    丁继坤 2/26/2009 韩城市 农民 4 2
    丁营村 3/3/2009 睢县 宣传部 4 4
    丁营村 3/3/2009 睢县 组织 4 4
    不知道你所说的结果不对是指哪个人的?
      

  15.   

    是指 “伊辛巴耶娃” 这个结果就不对了
    另外len这个函数在MYSQL里应该是 length阿
      

  16.   

    选择“伊辛巴耶娃”的时候,结果是:+------------+------------+--------+--------+-----+-------+
    | name       | ttime      | place  | word   | wgt | total |
    +------------+------------+--------+--------+-----+-------+
    | 伊辛巴耶娃 | 2009-03-01 | 北京市 | 撑杆跳 |  59 |   125 | 
    | 伊辛巴耶娃 | 2009-03-01 | 北京市 | 抵达   |  84 |   125 | 
    +------------+------------+--------+--------+-----+-------+
    实际上,伊辛巴耶娃在其他日期也有好多数据我要取够10条噢。如果有的话。
      

  17.   

    name ttime place word wgt total
    伊辛巴耶娃 3/3/2009 北京市 小学 10 9
    伊辛巴耶娃 3/3/2009 北京市 来到 9 9
    伊辛巴耶娃 3/2/2009 北京市 女皇 13 13
    伊辛巴耶娃 3/2/2009 北京市 撑杆跳 13 13
    伊辛巴耶娃 3/1/2009 北京市 抵达 84 125
    伊辛巴耶娃 3/1/2009 北京市 撑杆跳 59 125select a.name,a.ttime,a.place,a.word,a.wgt,a.total 
    from trace a inner join trace b on a.name=b.name and a.ttime=b.ttime and (
            b.total>a.total 
            or (b.total=a.total and b.wgt>a.wgt)
            or (b.total=a.total and b.wgt=a.wgt and len(b.word)>length(a.word))
            or (b.total=a.total and b.wgt=a.wgt and len(b.word)=length(a.word) and b.word>=a.word)
            )
    where a.name='伊辛巴耶娃'
    group by a.name,a.ttime,a.place,a.word,a.wgt,a.total 
    having count(*)<=2
    order by a.ttime desc
      

  18.   

    你将正确结果贴出来,就好测试:
    修改
    SELECT a.name, a.tTime, a.WORD, A.WGT,A.PLACE,a.total 
    FROM trace AS a LEFT JOIN trace AS b ON
    a.tTime=b.tTime 
    AND a.name=b.name
    and (b.total>a.total 
    or (b.total=a.total and b.wgt>a.wgt)
    or (b.total=a.total and b.wgt=a.wgt and length(b.word)>length(a.word))
    or (b.total=a.total and b.wgt=a.wgt and length(b.word)=length(a.word) and b.word>=a.word)
            )
    where a.name='伊辛巴耶娃'GROUP BY a.name, a.tTime, a.WORD, A.WGT,A.PLACE,a.total 
    HAVING COUNT(B.WORD) <=2
    ORDER BY A.NAME, a.tTime DESC增加3种情况的判断