mysql查询以检索每种项目类型的前2条记录

时间:2018-08-31 05:50:14

标签: sql mariadb greatest-n-per-group

我有一张类似的桌子

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

我的意思是对于每个不同的项目,查询需要输出前两个项目标题 还请给我查询

获取每个项目的最后10或n行,而不是前2行

4 个答案:

答案 0 :(得分:3)

尝试此查询:

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

Demo

答案 1 :(得分:2)

这是最适合行号和等级之类的分析功能的问题。但是,由于您的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;

Demo

答案 2 :(得分:0)

我将在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并用LIMIT10修改n子句。

答案 3 :(得分:0)

这将起作用,假设每个项目至少有两行:

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
                         );