MYSQL逐列分组,每组2行
我需要每组2个idMYSQL逐列分组,每组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_
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