假设我有一个包含几个字段的表,例如A、B、C、D
我需要按字段 A 进行分组,并从 B、C、D 中选择出现次数最多的值。
示例:
+---+---+---+----+
| A | B | C | D |
+---+---+---+----+
| 1 | 3 | 5 | 15 |
+---+---+---+----+
| 1 | 5 | 6 | 32 |
+---+---+---+----+
| 1 | 5 | 6 | 34 |
+---+---+---+----+
| 2 | 7 | 5 | 50 |
+---+---+---+----+
| 2 | 8 | 1 | 32 |
+---+---+---+----+
预期结果:
+---+---+---+----+
| A | B | C | D |
+---+---+---+----+
| 1 | 5 | 6 | 15 |
+---+---+---+----+
| 2 | 7 | 5 | 50 |
+---+---+---+----+
我看到了很多示例,如何使用 COUNT(*) 从一列中选择出现次数最多的值,而不是在此基础上使用 MAX。但在这种情况下该怎么办?
最佳答案
该查询看起来有点复杂,因为您必须对 3 列执行此操作。这个想法是通过按 a-b、a-c、a-d 的组合分组的计数对行进行排名,并获取每个组合的第一行。这是使用变量完成的。如果计数相同,则返回 b、c 或 d 的最小值。 (如果需要颠倒顺序,则可以更改此设置。)最后,还需要进行一次聚合才能将相应的值获取到一行。
select a,max(b),max(c),max(d)
from (
select a,b,c,d
from (select a,b,c,d,
@rn:=case when @prev=a then @rn+1 else 1 end as rank,
@prev:=a
from (select a,b,null as c,null as d,count(*) as cnt
from tbl
group by a,b
) t
cross join (select @rn:=0,@prev:='') r
order by a,cnt desc,b
) t
where rank = 1
union all
select a,b,c,d
from (select a,b,c,d,
@rn:=case when @prev=a then @rn+1 else 1 end as rank,
@prev:=a
from (select a,null as b,c,null as d,count(*) as cnt
from tbl
group by a,c
) t
cross join (select @rn:=0,@prev:='') r
order by a,cnt desc,c
) t
where rank = 1
union all
select a,b,c,d
from (select a,b,c,d,
@rn:=case when @prev=a then @rn+1 else 1 end as rank,
@prev:=a
from (select a,null as b,null as c,d,count(*) as cnt
from tbl
group by a,d
) t
cross join (select @rn:=0,@prev:='') r
order by a,cnt desc,d
) t
where rank = 1
) t
group by a
关于mysql - 在 MYSQL 中,GROUP BY 之后在几个字段中选择最常出现的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47577657/