设计思路
当mysql查询有很多分类时,可能只需要每种分类的前三或者前十的数据,不需要返回所有的结果,所以我们可以给不同种类的数据添加序号,然后通过序号来筛选结果
例:建一张工人工作质量表,用年份和质量来分类
CREATE TABLE `work` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT '' COMMENT '姓名',
`years` int(11) DEFAULT 0 COMMENT '年份',
`type` varchar(32) DEFAULT '' COMMENT '质量类型: 高 中 低 不合格',
`count` int(11) DEFAULT 0 COMMENT '工作量',
PRIMARY KEY (`id`),
UNIQUE KEY(`name`,`years`,`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
给新建的表添加一些数据
INSERT INTO `work` (`name`, `type`, `years`, `count`) VALUES ('张三', '高', 2020, 0);
INSERT INTO `work` (`name`, `type`, `years`, `count`) VALUES ('张三', '中', 2020, 200);
INSERT INTO `work` (`name`, `type`, `years`, `count`) VALUES ('张三', '低', 2020, 200);
INSERT INTO `work` (`name`, `type`, `years`, `count`) VALUES ('张三', '不合格', 2020, 600);
INSERT INTO `work` (`name`, `type`, `years`, `count`) VALUES ('李四', '高', 2020, 800);
INSERT INTO `work` (`name`, `type`, `years`, `count`) VALUES ('李四', '中', 2020, 100);
INSERT INTO `work` (`name`, `type`, `years`, `count`) VALUES ('李四', '低', 2020, 50);
INSERT INTO `work` (`name`, `type`, `years`, `count`) VALUES ('李四', '不合格', 2020, 50);
INSERT INTO `work` ( `name`, `type`, `years`, `count`) VALUES( '李四', '高', 2018, 100);
INSERT INTO `work` ( `name`, `type`, `years`, `count`) VALUES( '李四', '中', 2018, 200);
INSERT INTO `work` ( `name`, `type`, `years`, `count`) VALUES( '李四', '低', 2018, 500);
INSERT INTO `work` ( `name`, `type`, `years`, `count`) VALUES( '李四', '不合格', 2018, 200);
查询每人每年工作数量前3的数据
1.直接查询
SELECT name,type,years,count FROM work ORDER BY name DESC,years DESC,count DESC
查询的结果发现有很多是不需要的
name | type | years | count |
---|---|---|---|
李四 | 高 | 2020 | 800 |
李四 | 中 | 2020 | 100 |
李四 | 低 | 2020 | 50 |
李四 | 不合格 | 2020 | 50 |
李四 | 低 | 2018 | 500 |
李四 | 中 | 2018 | 200 |
李四 | 不合格 | 2018 | 200 |
李四 | 高 | 2018 | 100 |
张三 | 不合格 | 2020 | 600 |
张三 | 中 | 2020 | 200 |
张三 | 低 | 2020 | 200 |
张三 | 高 | 2020 | 0 |
2.添加序号筛选查询(通过数值排序添加序号,再将序号大于3的去除)
SELECT name, type, years, count
FROM (
SELECT CASE
WHEN @name = name
AND @years = years THEN @ordinal := @ordinal + 1
ELSE @ordinal := 1
END AS ordinal, @name := name AS name, @years := years AS years
, type, count
FROM (
SELECT name, type, years, count
FROM work, (
SELECT @ordinal := 0, @name := ‘’
, @years := 0
) t1
ORDER BY name DESC, years DESC, count DESC
) t2
) t3
WHERE ordinal <= 3
查询的结果
name | type | years | count |
---|---|---|---|
李四 | 高 | 2020 | 800 |
李四 | 中 | 2020 | 100 |
李四 | 低 | 2020 | 50 |
李四 | 低 | 2018 | 500 |
李四 | 中 | 2018 | 200 |
李四 | 不合格 | 2018 | 200 |
张三 | 不合格 | 2020 | 600 |
张三 | 中 | 2020 | 200 |
张三 | 低 | 2020 | 200 |