数据库
首页 > 数据库> > mysql-从M个组中选择前N行

mysql-从M个组中选择前N行

作者:互联网

我有这张桌子:

CREATE TABLE IF NOT EXISTS `catalog_sites` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `cat_id` int(10) unsigned NOT NULL,
  `date` datetime NOT NULL,
  `url` varchar(255) NOT NULL,
  `title` varchar(255) NOT NULL,
  `description` varchar(255) NOT NULL,
  `keywords` varchar(255) NOT NULL,
  `visited` int(10) unsigned NOT NULL,
  `shown` int(10) unsigned NOT NULL,
  `meta_try` int(1) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `url` (`url`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

我认为我的问题很简单,但似乎找不到合适的解决方案.

因此,这是一个包含网站的表格,我希望获得6个不同类别的6个网站(cat_id,总计:36行),每个类别的评分最高.评级是按访问过的/显示的来计算的.

我应该得到36行,其中包含6个顶级类别(我们可以通过按AVG(已访问/显示)进行排序来找到它们),并在这6个类别中的每个类别中拥有6个顶级网站.

如果您有任何想法可能会有所不同,请告诉我.

解决方法:

这应该使用MySQL变量为您提供所需的信息,内部查询将预先计算访问/显示的排名,并根据所需条件使用顺序…每个类别,最高排名…,然后使用@vars将保持@RankSeq顺序为1-?每个类别.通过该预查询(别名为PQ),OUTER查询仅查询URL的排名序列< = 6的预查询. 为了进一步确保您仅获得前6个类别,内部的PreQuery还为“ TopCategories”(别名)设置了预查询/限制

select
      PQ.URL,
      PQ.Cat_ID,
      PQ.Rank,
      PQ.URLRankSeq
   from 
      ( select 
              CS.cat_id,
              (CS.visited / CS.shown ) as Rank,
              CS.url,
              @RankSeq := if( @LastCat = CS.Cat_ID, @RankSeq +1, 1 ) URLRankSeq,
              @LastCat := CS.Cat_ID as ignoreIt
           from
              ( select cat_id, 
                       avg( visited / shown )
                   from catalog_sites
                   group by 1
                   order by 2 desc
                   limit 6 ) TopCategories

              JOIN catalog_sites CS
                 on TopCategories.Cat_ID = CS.Cat_ID,

              (select @RankSeq := 0, @LastCat = 0 ) SQLVars   
           order by 
              CS.cat_id,
              Rank ) PQ
    where
      PQ.URLRankSeq <= 6

标签:rows,greatest-n-per-group,mysql,group-by
来源: https://codeday.me/bug/20191202/2086534.html