mysql限制分组

时间:2019-03-06 14:33:59

标签: mysql group-by

说我有此表字段:

project.rootProject.gradle.ext.MY_PROPERTY_NAME

说我需要按Field1分组(因为我需要对数据进行一些计算), 有没有办法只检索按Field2(排序的desc)分组的前2个元素?

因此,在此示例中,我想检索:

Field1  Field2 Field3
a       1      1
a       1      2
a       1      3
a       1      4
a       2      1
a       2      2
a       2      3
a       3      1
b       1      1
b       1      2
b       1      3
b       2      1
c       1      1

会像

a,3,1
a,2,3
a,2,2
a,1,4
a,1,3
b,1,2
b,1,1
b,2,1
c,1,1

2 个答案:

答案 0 :(得分:2)

如果您使用的是MySQL 8+或更高版本,则解决此问题的一种好方法是使用ROW_NUMBER

WITH cte AS (
    SELECT Field1, Field2, Field3,
        ROW_NUMBER() OVER (PARTITION BY Field1, Field2 ORDER BY Field3 DESC) rn
    FROM yourTable
)

SELECT Field1, Field2, Field3
FROM cte
WHERE rn <= 2
ORDER BY Field1, Field2 DESC, Field3;

enter image description here

Demo

如果不是使用MySQL 8+,则此问题会变得相当冗长,很快。在MySQL 5.7或更早版本中,执行此操作的最佳方法是使用会话变量来模拟ROW_NUMBER。但是,这需要一些冗长的代码。您还可以尝试将每个组的前两个条目隔离开来,但其中两个条目将花费一些冗长的代码。确实,如果您长期需要运行这样的查询,请考虑升级到MySQL 8 +。

答案 1 :(得分:1)

MySQL 8.0之前的解决方案:

仅列出每个(Field1, Field2)组的最后两个值:

select *
from test t
where t.Field3 >= coalesce((
  select t1.Field3
  from test t1
  where t1.Field1 = t.Field1
    and t1.Field2 = t.Field2
  order by t1.Field3 desc
  limit 1
  offset 1
), 0)
order by Field1, Field2, Field3;

结果:

Field1  Field2  Field3
a       1       3
a       1       4
a       2       2
a       2       3
a       3       1
b       1       2
b       1       3
b       2       1
c       1       1

获取每个Field1组的SUM:

select t.Field1
     , sum(Field2)
     , sum(Field3)
from test t
where t.Field3 >= coalesce((
  select t1.Field3
  from test t1
  where t1.Field1 = t.Field1
    and t1.Field2 = t.Field2
  order by t1.Field3 desc
  limit 1
  offset 1
), 0)
group by t.Field1

结果:

Field1  sum(Field2)     sum(Field3)
a       9               13
b       4               6
c       1               1

Fiddle demo

注意:当(Filed1, Filed2, Filed3)的组合为UNIQUE时,此方法工作正常。如果Field3可以在(Field1, Field2)组中重复,则我们需要更复杂的逻辑以将结果限制为每组两行。