经常遇到一个表,有多个类别,每个类别,下面有多个小类别,每个小类别下面又有多条记录的情况,要求取出每个大类别下面的三条记录。
数据库;
CREATE TABLE `NewTable` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`acar_id` int(11) NOT NULL ,
`ascore_id` int(11) NOT NULL COMMENT '车型评分ID' ,
`score` int(11) NOT NULL COMMENT '评分' ,
`type` int(11) NOT NULL COMMENT '类型(101视觉设计,102触觉质感,103静谧性,211驾驶员头部空间)' ,
`content` varchar(400) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '评价' ,
`photo` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片' ,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
COMMENT='车型评分详情'
AUTO_INCREMENT=1051
ROW_FORMAT=COMPACT
数据:
需求
对于一个acar_id下面,只显示3小项(视觉设计、触觉质感、静谧性,若该三项未被评价,则顺序后推显示)及3小所属的大项名称及大项分数,点击“全部内容”“文字描述”“图”时,新开标签页查看全部内容
答案:
SELECT b.`acar_id`,b.`id` ,b.`id` % 3,CONCAT(b.`acar_id`, b.`id` % 3) FROM
`appraise_score_detail` b
WHERE
b.acar_id IN (29,30)
GROUP BY
CONCAT(b.`acar_id`, b.`id` % 3)
ORDER BY
b.id
解释一下:
GROUP BY
CONCAT(b.`acar_id`, b.`id` % 3)
如果上面的sql去除 group by是这样的,
SELECT b.`acar_id`,b.`id` ,b.`id` % 3,CONCAT(b.`acar_id`, b.`id` % 3) FROM
`appraise_score_detail` b
WHERE
b.acar_id IN (29,30)
ORDER BY
b.id
效果:
将acar_id下面的数据通过CONCAT(b.`acar_id`, b.`id` % 3)分为三种情况,然后在使用groupby
下面的链接是同样的问题,不过是别的解决方案:
https://segmentfault.com/q/1010000011404345/a-1020000011404530
可以参考。
还有遇到过这种写法的,可以提供思路。
第一种:
SELECT
a.*
FROM
appraise_score_detail a
LEFT JOIN appraise_score_detail b
on a.acar_id = b.acar_id AND a.score > b.score
where a.acar_id IN (11, 12, 13)
GROUP BY a.id
HAVING COUNT(a.id)<3
ORDER BY a.acar_id desc
第二种:
SELECT
a.*
FROM
appraise_score_detail a
WHERE
(SELECT COUNT(1)
FROM appraise_score_detail b
WHERE
a.acar_id = b.acar_id
AND a.score >=b.score
) < 3;