Mysql 如何从结果行中提取所需的行数?
我想通过将结果行中满足条件的行数限制为n来进行提取 有两张桌子Mysql 如何从结果行中提取所需的行数?,mysql,Mysql,我想通过将结果行中满足条件的行数限制为n来进行提取 有两张桌子 tb_info -------------------------- id(PK) | number | status | -------------------------- 1 | 1 | A | 2 | 1 | B | 3 | 2 | B | 4 | 2 | A | 5 | 3
tb_info
--------------------------
id(PK) | number | status |
--------------------------
1 | 1 | A |
2 | 1 | B |
3 | 2 | B |
4 | 2 | A |
5 | 3 | B |
6 | 3 | A |
7 | 4 | C |
8 | 4 | A |
9 | 5 | C |
10 | 6 | A |
tb_status
---------------------
st_id(PK) | status
---------------------
1 | A
2 | B
3 | C
然后运行查询以获得以下结果:
选择id、编号、状态
从tb_信息
其中number您需要按状态列对结果进行排序,以便
SELECT id, number, status FROM tb_info WHERE number <= 5 ORDER BY id, status
或者只是
SELECT id, number, status FROM tb_info WHERE number <= 5 ORDER BY status
应使用变量对每个状态的编号进行排序:
SET @rn := 0;
SET @status := '';
SELECT id, number, `status` FROM (
SELECT @rn := CASE
WHEN @status = `status` THEN @rn + 1
ELSE 1
END AS rn, number, `status`, id,
@status := `status`
FROM tb_info
WHERE number <= 5
ORDER BY `status`, number
) t
WHERE rn <= 2
这是与@forpas相同的解决方案,包含tb_状态
drop table if exists tb_info,tb_status;
create table tb_info
(id int primary key, number int, status varchar(1));
insert into tb_info values
( 1 , 1 , 'A' ),
( 2 , 1 , 'B' ),
( 3 , 2 , 'B' ),
( 4 , 2 , 'A' ),
( 5 , 3 , 'B' ),
( 6 , 3 , 'A' ),
( 7 , 4 , 'C' ),
( 8 , 4 , 'A' ),
( 9 , 5 , 'C' ),
( 10 , 6 , 'A' ),
( 11 , 1 , 'd' ),
( 12 , 3 , 'd' );
create table tb_status
( st_id int primary key, status varchar(1));
insert into tb_status values
( 1 , 'A'),
( 2 , 'B'),
( 3 , 'C');
select s.id,s.number,s.status
from tb_status
join
(select t.id,t.number,t.status,
if(t.`status` <> @p , @rn:=1,@rn:=@rn+1) rn,
@p:=t.`status` p
from tb_info t
cross join (select @rn:=0,@p:=0) r
order by t.status,t.number
) s
on s.status = tb_status.status
where s.rn <= 2
order by s.status,s.rn;
+----+--------+--------+
| id | number | status |
+----+--------+--------+
| 1 | 1 | A |
| 4 | 2 | A |
| 2 | 1 | B |
| 3 | 2 | B |
| 7 | 4 | C |
| 9 | 5 | C |
+----+--------+--------+
6 rows in set (0.00 sec)
注释d已删除。您使用的是哪一版本的mysql?@p.Salmon mysql版本为5.7.27不是结果。我想我想从满足所需条件的行中得到2行。这个输出是什么?你的答案包含在我的问题中。我想让状态栏的A、B和C各打印2个输出。对于8.0之前的版本-注意,我添加了一个小“+0”以避免隐式的强制转换错误。@草莓为真,用户在评论中说版本是5.7.27,它仍然可以通过重新组织一点来进行修改,以便与5.7和8.0兼容,当然,在8中有更简单的方法可用。0@Strawberry添加+0将结果的状态限制为一种情况。@P.Salmon我意识到不同版本有不同的解决方案。谢谢你的回答,谢谢你对我问题的真诚回答。我把你的答案作为一个测试代码,并做了很多研究。
| id | number | status |
| --- | ------ | ------ |
| 1 | 1 | A |
| 4 | 2 | A |
| 2 | 1 | B |
| 3 | 2 | B |
| 7 | 4 | C |
| 9 | 5 | C |
drop table if exists tb_info,tb_status;
create table tb_info
(id int primary key, number int, status varchar(1));
insert into tb_info values
( 1 , 1 , 'A' ),
( 2 , 1 , 'B' ),
( 3 , 2 , 'B' ),
( 4 , 2 , 'A' ),
( 5 , 3 , 'B' ),
( 6 , 3 , 'A' ),
( 7 , 4 , 'C' ),
( 8 , 4 , 'A' ),
( 9 , 5 , 'C' ),
( 10 , 6 , 'A' ),
( 11 , 1 , 'd' ),
( 12 , 3 , 'd' );
create table tb_status
( st_id int primary key, status varchar(1));
insert into tb_status values
( 1 , 'A'),
( 2 , 'B'),
( 3 , 'C');
select s.id,s.number,s.status
from tb_status
join
(select t.id,t.number,t.status,
if(t.`status` <> @p , @rn:=1,@rn:=@rn+1) rn,
@p:=t.`status` p
from tb_info t
cross join (select @rn:=0,@p:=0) r
order by t.status,t.number
) s
on s.status = tb_status.status
where s.rn <= 2
order by s.status,s.rn;
+----+--------+--------+
| id | number | status |
+----+--------+--------+
| 1 | 1 | A |
| 4 | 2 | A |
| 2 | 1 | B |
| 3 | 2 | B |
| 7 | 4 | C |
| 9 | 5 | C |
+----+--------+--------+
6 rows in set (0.00 sec)