MYSQL逐列分组,每组2行

MYSQL逐列分组,每组2行,mysql,sql,group-by,greatest-n-per-group,Mysql,Sql,Group By,Greatest N Per Group,我需要每组2个id SELECT `id`, `category`.`cat_name` FROM `info` LEFT JOIN `category` ON `info`.`cat_id` = `category`.`cat_id` WHERE `category`.`cat_name` IS NOT NULL GROUP BY `category`.`cat_name` ORDER BY `category`.`cat_name` ASC 如何做到这一点 样本数据: id cat_

我需要每组2个id

SELECT `id`, `category`.`cat_name` 
FROM `info`
LEFT JOIN `category` ON `info`.`cat_id` = `category`.`cat_id`
WHERE `category`.`cat_name` IS NOT NULL
GROUP BY `category`.`cat_name`
ORDER BY `category`.`cat_name` ASC 
如何做到这一点

样本数据:

id  cat_name
1   Cat-1
2   Cat-1
3   Cat-2
4   Cat-1
5   Cat-2
6   Cat-1
7   Cat-2
输出将是:

id  cat_name
6   Cat-1
4   Cat-1
7   Cat-2
5   Cat-2

如果需要两个任意ID,请使用最小值和最大值:

注意:您使用的是左联接,然后通过第二个表中的列进行聚合。这通常不是一个好主意,因为非匹配项都放在一个空组中。此外,WHERE子句将左连接变为内部连接,所以我已经解决了这个问题。WHERE子句可能是必需的,也可能不是必需的,这取决于cat_name是否为NULL

如果您想要两个最大或最小的,并且可以将它们放在同一列中:

SELECT c.`cat_name`,
       substring_index(group_concat id order by id), ',', 2) as ids_2 
FROM `info` i INNER JOIN
     `category` c
     ON i.`cat_id` = c.`cat_id`
WHERE c.`cat_name` IS NOT NULL
GROUP BY c`.`cat_name`
ORDER BY c.`cat_name` ASC ;

.

在支持窗口功能的数据库中,您可以按类别名称顺序(按id DESC)枚举分区上每个组行号中每个记录的位置,然后选择相对位置1或2的记录

在MySQL中,您可以通过一个自连接来模拟这一点,该自连接统计id大于或等于同一cat_名称分区的记录数。。。ORDER BY id DESC。cat_名称组中的记录1只有一条>=其id的记录,而记录N有N条这样的记录

这个问题

 SELECT id, cat_name
   FROM (   SELECT c.id, c.cat_name, COUNT(1) AS relative_position_in_group
              FROM category c
         LEFT JOIN category others
                ON c.cat_name = others.cat_name
                   AND
                   c.id <= others.id
          GROUP BY 1, 2) d
   WHERE relative_position_in_group <= 2
ORDER BY cat_name, id DESC;
您的查询类似于按cat_名称从mytable group中选择id、cat_名称,然后将其更新为按cat_名称从mytable group中选择Select SUBSTRING_INDEXgroup_concatid’、’、2、cat_名称,您将得到如下输出

id  cat_name
1,2   Cat-1
3,5   Cat-2

这有帮助吗?

您只需要在查询末尾添加限制选项,并按降序排序,如下所示:

SELECT `id`, `category`.`cat_name` 
FROM `info`
LEFT JOIN `category` ON `info`.`cat_id` = `category`.`cat_id`
WHERE `category`.`cat_name` IS NOT NULL
GROUP BY `category`.`cat_name`
ORDER BY `category`.`cat_name` DESC
LIMIT 2 

非常简单的按ID分组。这是组重复数据

我已经为您编写了查询。我希望它能解决您的问题:

SELECT 
    id, cat_name
FROM
    (SELECT 
        *,
            @prevcat,
            CASE
                WHEN cat_name != @prevcat THEN @rownum:=0
            END,
            @rownum:=@rownum + 1 AS cnt,
            @prevcat:=cat_name
    FROM
        category
    CROSS JOIN (SELECT @rownum:=0, @prevcat:='') r
    ORDER BY cat_name ASC , id DESC) AS t
WHERE
    t.cnt <= 2;

最好使用rank函数下面的示例查询将有助于检查输出

select a.* from 
(
select a, b ,rank() over(partition by b order by a desc) as rank
from a
group by b,a) a

where rank<=2

请试试这个,它在给定的示例数据中起作用

SELECT `id`, `category`.`cat_name`
FROM `info`
LEFT JOIN `category` ON `info`.`cat_id` = `category`.`cat_id`
WHERE `category`.`cat_name` IS NOT NULL and (SELECT count(*) 
FROM info t
WHERE t.id>=info.id and t.cat_id=category.cat_id )<3

GROUP BY `category`.`cat_name`,id
ORDER BY `category`.`cat_name` ASC

好吧,这很难看,但看起来很管用

select
cat_name,
max(id) as maxid
from
table1
group by cat_name
union all
select
cat_name,
max(id) as maxid
from
table1
where not exists
(select 
  cat_name,
  maxid
  from 
  (select cat_name,max(id) as maxid from table1  group by cat_name) t
  where t.cat_name = table1.cat_name and t.maxid = table1.id)
group by cat_name
order by cat_name
基本上,它会获取每个cat_名称的max,然后将其合并到第二个查询,该查询排除每个cat_名称的实际max id,从而获得每个cat_名称的第二大id。希望这一切都有意义

select id, cat_name from 

(
 select @rank:=if(@prev_cat=cat_name,@rank+1,1) as rank,
         id,cat_name,@prev_cat:=cat_name
from Table1,(select @rank:=0, @prev_cat:="")t
   order by cat_name, id desc
) temp

where temp.rank<=2

您可以在

处验证结果。请提供样本数据和所需结果。选择GROUP_CONCATinfo.id、GROUP_ConcatCatCategory.id,…您想要哪两行?有两排吗?两行ID最高,这似乎是您的输出所显示的?我需要每组最新的2行@Rickjames您是否检查了相关问题?@Chayan,如果您发现它适合您的问题解决方案,请选择它作为答案。我认为它不起作用。这将限制最终结果为2,而不是基于每个组。MySQL没有排名功能Thaks用于分享您的知识!
SELECT `id`, `category`.`cat_name`
FROM `info`
LEFT JOIN `category` ON `info`.`cat_id` = `category`.`cat_id`
WHERE `category`.`cat_name` IS NOT NULL and (SELECT count(*) 
FROM info t
WHERE t.id>=info.id and t.cat_id=category.cat_id )<3

GROUP BY `category`.`cat_name`,id
ORDER BY `category`.`cat_name` ASC
select
cat_name,
max(id) as maxid
from
table1
group by cat_name
union all
select
cat_name,
max(id) as maxid
from
table1
where not exists
(select 
  cat_name,
  maxid
  from 
  (select cat_name,max(id) as maxid from table1  group by cat_name) t
  where t.cat_name = table1.cat_name and t.maxid = table1.id)
group by cat_name
order by cat_name
select id, cat_name from 

(
 select @rank:=if(@prev_cat=cat_name,@rank+1,1) as rank,
         id,cat_name,@prev_cat:=cat_name
from Table1,(select @rank:=0, @prev_cat:="")t
   order by cat_name, id desc
) temp

where temp.rank<=2