MYSQL 分組排名


今天遇到一個MYSQL排序的問題,要求按某列進行分組,組內進行排序.

百度一下發現MYSQL不支持row_number(),rank()等函數.

采用的辦法如下,我們首先創建一個測試表:

--創建表
create table Rank_test(ID int,SCORE int,grp int)

--插入數據
insert into Rank_test values(1 ,     28,1);
insert into Rank_test values(2 ,     33,1);
insert into Rank_test values(3 ,     33,1);
insert into Rank_test values(4 ,     89,1);
insert into Rank_test values(5 ,     99,1);
insert into Rank_test values(6 ,     68,1);
insert into Rank_test values(7 ,     68,1);
insert into Rank_test values(8 ,     78,1);
insert into Rank_test values(9 ,     88,1);
insert into Rank_test values(10,    90 ,1);
insert into Rank_test values(11,     28,2);           
insert into Rank_test values(12,     33,2);           
insert into Rank_test values(13,     33,2);    
insert into Rank_test values(14,     89,2);           
insert into Rank_test values(15,     99,2);           
insert into Rank_test values(16,     68,2);           
insert into Rank_test values(17,     68,2);           
insert into Rank_test values(18,     78,2);           
insert into Rank_test values(19,     88,2);           
insert into Rank_test values(20,    90 ,2);         

分組排序的SQL代碼:

SELECT id,  
       score,  
       rank  
  FROM (SELECT tmp.id,  
               tmp.score,                              
               @rank := (case when @Grp = grp then @rank + 1 else 1 end) AS rank  ,
               @Grp:=grp as grp2
          FROM (SELECT id,  
                       score,
                       grp
                  FROM rank_test) tmp,  
               (SELECT @rank   := 0,@grp:=0) a
            order by grp,score desc) RESULT
;  

結果如下:

 

測試結果OK,但重點是套用到我們的SQL中后,排序結果完全不是我們預期中的,而且沒有找到規律.

經過幾次嘗試,最后重新改寫了SQL代碼,終於成功了.

原因是套用下面這段代碼時,我們是用了幾張表進行關聯(inner join ),最后將inner join 的表全部改為where 語句中的子句,結果滿足我們的預期.

(SELECT id,  
                       score,
                       grp
                  FROM rank_test) tmp,

所以建議在這里的代碼盡量使用單表,不要多張表關聯

附上修改前后的代碼:(紅色部分是修改前,綠色部分是修改后)

select * from (
select evtdate
        ,stkabb,chng,PCTCSHG,cshg,SHHNAME
        ,@rank := (case when @SHHNAME=SHHNAME then @rank + 1 
                                        else 1 end) AS rank  
        ,@SHHNAME:=SHHNAME
from 
(
select tt.SHHNAME -- 股東名稱
      ,s.evtdate  -- 變動日期
      ,r.stkabb   -- 變動股票名稱
      ,ifnull(s.RLDSHG,s.cshg-s.SHGBCH)/10000 as chng -- 變動股數(萬股)
      ,s.cshg/10000 as cshg-- 變動后持股(萬股)
      ,s.PCTCSHG -- 變動后持股比例%
  from pgenius.hk_stkcode r inner join pgenius.HK_SAKCHMJSHH s on r.comunic = s.comunic inner join (select distinct b.SHHNAME from pgenius.hk_stkcode a inner join pgenius.HK_SAKCHMJSHH b on a.comunic = b.comunic and b.evtdate = (select max(evtdate) from pgenius.HK_SAKCHMJSHH where comunic = b.comunic and SHHNAME = b.SHHNAME and NTUREFCINTRTS = b.NTUREFCINTRTS) where a.lssturefc = 1
          and b.cshg > 0
          and a.stkcode = '00001' ) tt on s.SHHNAME = tt.SHHNAME
) t1,
(SELECT @rank := 0,@SHHNAME:='') t2
order by SHHNAME,evtdate desc,stkabb ) t

 

select t.*
        , o.stkabb 
from 
(
    select t1.*
            ,@rank := (case when @SHHNAME=SHHNAME then @rank + 1 
                                            else 1 end) AS rank  
            ,@SHHNAME:=SHHNAME
    from 
    (
        select s.evtdate ,ifnull(s.RLDSHG,s.cshg-s.SHGBCH)/10000 as chng -- 變動股數(萬股)
                    ,s.cshg/10000 as cshg-- 變動后持股(萬股)
                    ,s.PCTCSHG -- 變動后持股比例%
 ,SHHNAME ,s.COMUNIC from pgenius.HK_SAKCHMJSHH s where SHHNAME in ( select distinct shhname from pgenius.HK_SAKCHMJSHH a where comunic=(select COMUNIC from pgenius.hk_stkcode where stkcode='00001') and ISVALID=1 
            and not exists(select 1 from pgenius.HK_SAKCHMJSHH where COMUNIC=a.COMUNIC and SHHNAME=a.SHHNAME and evtdate>a.evtdate)
            and cshg > 0)
    ) t1,
    (SELECT @rank := 0,@SHHNAME:='') t2
    order by SHHNAME,evtdate desc 
) t
    inner join pgenius.hk_stkcode o on t.COMUNIC= o.COMUNIC
where t.rank<=10
order by shhname,rank

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM