如何按第一个字母分组

问题描述 投票:3回答:3

我在MySQL中有以下查询:

select val,count(val)
from ....
where ...
group by val

它给:

val   count
CE3    4
CE5    1
A3     12
BRICK4  5
BRICK2  2

我想只显示每个首字母数最多的行。这意味着所有以val开头的A都是一组,所有以val开头的B都是另一组...

预期的结果是:

val   count
CE3    4     /  CE3  CE5  are in group C , CE3 has higher count
A3     12    /  A3 is the only one in group A
BRICK4  5    / BRICK4  BRICK2  are in group B, BRICK4   has higher count

我怎样才能做到这一点?

编辑:我想要做的是在查询中创建一个临时列,代表组如下:

val   count  group
CE3    4      C
CE5    1      C
A3     12     A
BRICK4  5     B
BRICK2  2     B

然后搜索每组具有最高计数值的行。但我不确定这是最好的方法

mysql sql
3个回答
6
投票

尝试这样的事情:

select
    val
    ,MAX(count) as count
    ,left(val,1) as first_letter
from (
    select
        val
        ,count(val) as count
    from tbl
    group by val
) a
group by left(val, 1);

首先得到countval从这个结果获得MAXcount分组的第一个字母

更新:(请向Vamsi Prabhala指出我的第一个解决方案不是最好的解决方案)

在获得每个countval之后,我使用一个变量来重做ROW_NUMBER()功能(来自MS-SQL)并从结果中选择第一行,由first_lettercount desc排序


select val, count, first_letter from (
  select
     @i:=CASE
          WHEN @first_letter = first_letter THEN @i + 1
          ELSE 1
     END as rn
     ,@first_letter:= a.first_letter as First_letter
     ,a.val
     ,a.count
  from (
      select
          val
          ,count(val) as count
          ,left(val,1) as first_letter
      from tbl
      group by val
  )a, (select @i:=0) b
  order by First_letter, count desc
  ) c
where rn = 1

3
投票

这可以通过变量来完成,以根据计数对行进行排名。

select val,val_cnt 
from (
select val,val_cnt,@rn:=case when @prev=left(val,1) then @rn+1 else 1 end as rnum,
@prev:=left(val,1)
from (select val,count(val) as val_cnt
      from ....
      where ...
      group by val
     ) t
cross join (select @rn:=0,@prev:='') r
order by left(val,1),val_cnt desc,val --added val to order by to break ties 
) t 
where rnum=1

1
投票

不确定这是你想要的:

让我们从每个起始字母得到最大值:

 SELECT LEFT(val, 1) as l_val, MAX(count_val)
 FROM (
   select val,count(val) as count_val
   from ....
   where ...
   group by val
 ) t
 GROUP BY l_val

那么你想要val出现:

SELECT t2.val, t1.max_val
FROM (
 SELECT LEFT(val, 1) as l_val, MAX(count_val) as max_val
 FROM (
   select val,count(val) as count_val
   from ....
   where ...
   group by val
 ) t
 GROUP BY l_val) t1
 INNER JOIN `YOUR_table` t2 ON LEFT(t2.val,1) = t1.l_val
© www.soinside.com 2019 - 2024. All rights reserved.