MySQL запрос для получения первых 2 записей для каждого типа элемента - PullRequest
0 голосов
/ 31 августа 2018

У меня есть таблица, как

rowid    item      item title
1        pen       pen 1
2        pen       pen 2
3        pencil    pencil 1
4        pencil    pencil 2
5        pen       pen 3
6        paper     paper 1
7        pencil    pencil 3
8        paper     paper 2
9        paper     paper 3

Мне нужен запрос, который может выводить, как это в MySQL

rowid    item      item title
1        pen       pen 1
2        pen       pen 2
6        paper     paper 1
8        paper     paper 2
3        pencil    pencil 1
4        pencil    pencil 2

Я имею в виду, что для каждого отдельного элемента запрос должен выводить первые 2 заголовка элемента Также, пожалуйста, дайте мне запрос

чтобы получить последние 10 или n строк для каждого элемента вместо первых 2 строк

Ответы [ 4 ]

0 голосов
/ 31 августа 2018

Это будет работать при условии, что для каждого элемента есть как минимум две строки:

select t.*
from t
where t.rowid <= (select t2.rowid
                  from t2
                  where t2.item = t.item
                  order by t2.rowid
                  limit 1, 1
                 );

Вы можете обрабатывать элементы только с одной строкой, используя coalesce():

select t.*
from t
where t.rowid <= coalesce( (select t2.rowid
                            from t2
                            where t2.item = t.item
                            order by t2.rowid
                            limit 1, 1
                           ),
                           t.rowid
                         );
0 голосов
/ 31 августа 2018

Это проблема, которая лучше всего подходит для аналитических функций, таких как номер строки и ранг. Но, поскольку ваша версия MariaDB не поддерживает их, мы должны найти обходной путь.

Одним из подходов, который не требует динамического SQL, является создание запроса, который находит минимальные и минимальные значения rowid для каждой группы элементов. Затем мы просто присоединяем исходную таблицу к этому подзапросу, чтобы сохранить только первые две совпадающие строки.

SELECT t1.*
FROM yourTable t1
INNER JOIN
(
    SELECT a.item, b.min_rowid, MIN(a.rowid) AS next_min_rowid
    FROM yourTable a
    INNER JOIN
    (
        SELECT item, MIN(rowid) AS min_rowid
        FROM yourTable
        GROUP BY item
    ) b
        ON a.item = b.item
    WHERE a.rowid > b.min_rowid
    GROUP BY a.item, b.min_rowid
) t2
    ON t1.item = t2.item AND (t1.rowid = t2.min_rowid OR t1.rowid = t2.next_min_rowid)
ORDER BY
    t1.item, t1.rowid;

Демо

0 голосов
/ 31 августа 2018

Я бы использовал коррелированный подзапрос с предложением LIMIT:

SELECT t.*
FROM table t
WHERE rowid IN (SELECT t1.rowid 
                FROM table t1
                WHERE t1.item = t.item
                ORDER BY t1.itemtitle
                LIMIT 2 
               );

Если вы хотите последний itemtitle, тогда сделайте ORDER BY t1.itemtitle DESC и измените предложение LIMIT с помощью 10 или n.

0 голосов
/ 31 августа 2018

Попробуйте этот запрос:

select @rn := 1, @itemLag := '';

select rowid, item, itemTitle from (
    select rowid, 
           case when @itemLag = item then @rn := @rn + 1 else @rn := 1 end rn, 
           @itemLag := item, 
           item, 
           itemTitle
    from tbl
    order by item, rowid
) a where rn <= 2

Демо

...