MySQL выбирает определенное количество строк для каждого типа в определенном - PullRequest
0 голосов
/ 19 марта 2019

Я хотел бы выбрать первое определенное количество строк по группам определенного столбца. Например:

Исходные данные:

  index   type     value
0       1    a  0.716430
1       2    a  0.223650
2       3    a  0.375417
3       4    a  0.773874
4       5    a  0.802127
5       6    a  0.956563
6       7    b  0.377718
7       8    b  0.487772
8       9    b  0.672767
9      10    b  0.275895
10     11    b  0.981751
11     12    b  0.914780
12     13    b  0.940582
13     14    c  0.347563
14     15    c  0.101106
15     16    c  0.390205
16     17    c  0.235941
17     18    c  0.593234
18     19    c  0.904659

Я хотел бы выбрать первые 4 строки для каждого уникального значения type, и порядок будет index.

Таким образом, идеальный результат будет:

      index    type    value
0       1.0      a  0.716430
1       2.0      a  0.223650
2       3.0      a  0.375417
3       4.0      a  0.773874
4       7.0      b  0.377718
5       8.0      b  0.487772
6       9.0      b  0.672767
7      10.0      b  0.275895
8      14.0      c  0.347563
9      15.0      c  0.101106
10     16.0      c  0.390205
11     17.0      c  0.235941

Ответы [ 2 ]

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

Вы можете получить желаемый результат, самостоятельно присоединившись к вашей таблице на index, где значение index в объединенной таблице меньше, чем в первой, и выбрав только те строки, которые имеют <4 строки снижние значения индекса: </p>

SELECT t1.id, t1.index, t1.type, t1.value
FROM test t1
LEFT JOIN test t2 ON t2.index < t1.index AND t2.type = t1.type
GROUP BY t1.id, t1.index, t1.type, t1.value
HAVING COUNT(t2.index) < 4

Вывод:

id  index   type    value
0   1       a       0.71643
1   2       a       0.22365
2   3       a       0.375417
3   4       a       0.773874
6   7       b       0.377718
7   8       b       0.487772
8   9       b       0.672767
9   10      b       0.275895
13  14      c       0.347563
14  15      c       0.101106
15  16      c       0.390205
16  17      c       0.235941

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

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

row_number() является типичным решением для этого:

select t.*
from (select t.*,
             row_number() over (partition by type order by index) as seqnum
      from t
     ) t
where seqnum <= 4;

В более старых версиях MySQL вы можете сделать:

select tm.*
from telegram_message tm
where tm.index <= coalesce( (select tm2.index
                             from telegram_message tm2
                             where tm2.type = tm.type
                             order by tm2.index asc
                             limit 1 offset 3
                            ), tm.index
                          );

coalesce() означает, что все строки берутся, если для типа нет 4 строк.

...