mysql предел в группе по - PullRequest
0 голосов
/ 06 марта 2019

Скажите, у меня есть поля этой таблицы:

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

и скажите, что мне нужно сгруппировать по полю1 (потому что мне нужны некоторые вычисления для данных), Есть ли способ получить только первые 2 элемента, сгруппированных по Field2 (отсортировано по описанию)?

Так что для этого примера я хотел бы получить:

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

было бы что-то вроде

SELECT field1, 
       Sum(field2), 
       Sum(field3) 
FROM   table t1 
WHERE  t1.Field1 IN (SELECT t2.Field1 
                     FROM   table t2 
                     WHERE  t2.Field1 = t1.Field1 
                     ORDER  BY Field2, 
                               Field3 DESC 
                     LIMIT  2) 
GROUP  BY field1 

Ответы [ 2 ]

2 голосов
/ 06 марта 2019

Хороший способ справиться с этим, если вы используете 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

Демо

Если вы не используете MySQL 8+, то эта проблема становится довольно проблематичной, довольно быстро.Лучший способ сделать это в MySQL 5.7 или более ранней версии - использовать переменные сеанса для имитации ROW_NUMBER.Но для этого требуется некоторый подробный код.Вы также можете попытаться выделить две верхние записи на группу, но для этих двух потребуется некоторый подробный код.На самом деле, если у вас есть долгосрочная необходимость выполнять подобные запросы, подумайте об обновлении до MySQL 8+.

1 голос
/ 06 марта 2019

Решение до 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 группа:

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

Демонстрация скрипки

Примечание: это прекрасно работает, когда комбинация (Filed1, Filed2, Filed3) УНИКАЛЬНО.Если Field3 может быть продублировано в группе (Field1, Field2), нам потребуется более сложная логика, чтобы ограничить результат двумя строками в группе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...