MySQL 5.6 - DENSE_RANK like functionality without Order By

后端 未结 3 1843
北海茫月
北海茫月 2020-12-03 23:42

I have a table like this:

+------+-----------+
|caseID|groupVarian|
+------+-----------+
|1     |A,B,C,D,E  |
+------+-----------+
|2     |A,B,N,O,P  |
+----         


        
3条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-04 00:41

    Basically, you want to enumerate the variants. If you just want a number, then you could use the minimum id:

    select t.*, min_codeId as groupVariantId
    from t join
         (select groupVariant, min(codeId) as min_codeId
          from t
          group by groupVariant
         ) g
         on t.groupVariant = g.groupVariant;
    

    But that is not quite what you want. You appear to want them enumerated by the order they appear in the data. For that, you need variables. This is a bit tricky, but:

    select t.*, rn as groupVariantId
    from t join
         (select g.*,
                 (@rn := if(@gv = groupvariant, @gv,
                            if(@gv := groupvariant, @gv+1, @gv+1)
                           )
                 ) as rn
          from (select groupVariant, min(codeId) as min_codeId
                from t
                group by groupVariant
                order by min(codeId)
               ) g cross join
               (select @gv := '', @rn := 0) params
         ) g
         on t.groupVariant = g.groupVariant;
    

    Using variables is tricky. One important consideration: MySQL does not guarantee the order of evaluation of expressions in a SELECT. That means that a variable should not be assigned in one expression and then used in another -- because they could be evaluated in the wrong order (another answer has this mistake).

    In addition, the order by needs to take place in a subquery. MySQL does not guarantee that the variable assignment occurs before the sorting.

提交回复
热议问题