微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MYSQL-按限制分组

如何解决MYSQL-按限制分组

我认为MysqL中没有简单的方法。一种方法是通过为按rating_name分组的每一行生成一个行号,然后仅选择row_number为2或更少的行。在大多数数据库中,您可以使用以下方法进行此操作:

SELECT * FROM (
    SELECT
        rating_name,
        etc...,
        ROW_NUMBER() OVER (PARTITION BY rating_name ORDER BY good) AS rn
    FROM your_table
) T1
WHERE rn <= 2

不幸的是,MysqL不支持ROW_NUMBER语法。但是,您可以ROW_NUMBER使用变量进行模拟:

SELECT
    rating_name, id_markets, good, neutral, bad
FROM (
    SELECT
        *,
        @rn := CASE WHEN @prev_rating_name = rating_name THEN @rn + 1 ELSE 1 END AS rn,
        @prev_rating_name := rating_name
    FROM (
        SELECT
            rating_name,
            id_markets,
            SUM(COALESCE(rating_good, 0)) AS good,
            SUM(COALESCE(rating_neutral, 0)) AS neutral,
            SUM(COALESCE(rating_bad, 0)) AS bad
        FROM zzratings
        WHERE rating_year = YEAR(CURDATE()) AND rating_week = WEEK(CURDATE(), 1)
        GROUP BY rating_name, id_markets
    ) AS T1, (SELECT @prev_rating_name := '', @rn := 0) AS vars
    ORDER BY rating_name, good DESC
) AS T2
WHERE rn <= 2
ORDER BY rating_name, good DESC

对测试数据运行时的结果:

法国1 2 0 0
法国2 1 0 0
爱尔兰1 4 2 0
爱尔兰21 3 1 0
波兰1 3 1 0
波兰2 1 0 0

解决方法

有没有一种简单的方法可以将GROUP BY结果限制在前2位。以下查询返回所有结果。使用“ LIMIT 2”将整个列表减少到仅前2个条目。

select distinct(rating_name),id_markets,sum(rating_good) 'good',sum(rating_neutral)'neutral',sum(rating_bad) 'bad' 
 from ratings 
 where rating_year=year(curdate()) and rating_week= week(curdate(),1)
 group by rating_name,id_markets
 order by rating_name,sum(rating_good) 
 desc

结果如下:

波兰78 48 24 12 <-保持
波兰1 15 5 0 <-保持
波兰23 12 6 3
波兰2 5 0 0
波兰3 0 5 0
波兰4 0 0 5
爱尔兰1 9 3 0 <-保持
爱尔兰2 3 0 0 <-保持
爱尔兰3 0 3 0
爱尔兰4 0 0 3
法国12 24 12 6 <-保持
法国1 3 1 0 <-保持
法国231 1 0 0
法国2 1 0 0
法国4 0 0 1
法国3 0 1 0

谢谢乔恩


根据要求,我附上了表格结构和一些测试数据的副本。我的目标是创建一个视图,该视图具有每个唯一的rating_name的前2个结果

CREATE TABLE `zzratings` (
  `id` int(11) NOT NULL AUTO_INCREMENT,`id_markets` int(11) DEFAULT NULL,`id_account` int(11) DEFAULT NULL,`id_users` int(11) DEFAULT NULL,`dateTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP,`rating_good` int(11) DEFAULT NULL,`rating_neutral` int(11) DEFAULT NULL,`rating_bad` int(11) DEFAULT NULL,`rating_name` varchar(32) DEFAULT NULL,`rating_year` smallint(4) DEFAULT NULL,`rating_week` tinyint(4) DEFAULT NULL,`cash_balance` decimal(9,6) DEFAULT NULL,`cash_spend` decimal(9,PRIMARY KEY (`id`),KEY `rating_year` (`rating_year`),KEY `rating_week` (`rating_week`),KEY `rating_name` (`rating_name`)
) ENGINE=MyISAM AUTO_INCREMENT=2166690 DEFAULT CHARSET=latin1;

INSERT INTO `zzratings` (`id`,`id_markets`,`id_account`,`id_users`,`dateTime`,`rating_good`,`rating_neutral`,`rating_bad`,`rating_name`,`rating_year`,`rating_week`,`cash_balance`,`cash_spend`)
VALUES
    (63741,1,NULL,100,'poland',2010,15,NULL),(63742,101,(1,2,102,(63743,3,103,(63744,4,104,(63745,105,(63746,106,(63747,5,'ireland',(63748,(63749,(63750,(63751,(63752,(63753,(63754,(63755,(63756,(63757,34,(63758,(63759,(63760,(63761,21,(63762,(63763,(63764,(63765,(63766,(63767,(63768,'france',(63769,(63770,(63771,(63772,NULL);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。