zoukankan      html  css  js  c++  java
  • sql 分组查询前N名

    分组查询前十名

    表结构

    
    CREATE TABLE `tb_api_app_income_rank` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `product_id` varchar(64) DEFAULT '',
      `product_name` varchar(255) DEFAULT NULL,
      `publisher_id` varchar(64) DEFAULT NULL,
      `publisher_name` varchar(512) DEFAULT NULL,
      `company_id` varchar(64) DEFAULT NULL,
      `company_name` varchar(512) DEFAULT NULL,
      `category` varchar(64) DEFAULT NULL COMMENT '分类',
      `rank_type` varchar(32) DEFAULT NULL COMMENT '排行榜类型,0:免费,1:付费,2:畅销',
      `country` varchar(32) DEFAULT NULL,
      `rank` int(11) DEFAULT NULL COMMENT '在收入下载量排行榜的排名',
      `change_rank` int(11) DEFAULT NULL,
      `change_percent` decimal(11,6) DEFAULT NULL,
      `change_value` int(11) DEFAULT NULL,
      `price` decimal(11,2) DEFAULT NULL,
      `estimate` int(11) DEFAULT NULL,
      `downloads` int(11) DEFAULT NULL COMMENT '下载量',
      `income` int(11) DEFAULT NULL COMMENT '收入',
      `release_date` varchar(32) DEFAULT NULL,
      `is_new` int(11) DEFAULT '0' COMMENT '是否新品,0:不是,1:是。新品:距离当前时间往前推7天(昨日为第7日),release date在这7天之内,且该产品的appid是首次出现,才算做新品',
      `created_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
      `updated_at` datetime DEFAULT NULL,
      PRIMARY KEY (`id`,`created_at`),
      KEY `idx_apir_update_time` (`updated_at`) USING BTREE,
      KEY `idx_apir_ctime_country` (`country`,`created_at`) USING BTREE,
      KEY `idx_apir_aid` (`product_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=52188 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='app 收入下载量的排行榜,分免费、付费、畅销排行榜'
    
    
    1. 第一种方案
    SELECT
    	t1.*
    FROM
    	tb_api_app_income_rank t1
    WHERE
    	created_at = '2017-11-07 00:00:00'
    AND rank_type = 'grossing'
    AND change_rank = 1000
    AND (
    	SELECT
    		count(1)
    	FROM
    		tb_api_app_income_rank
    	WHERE
    		rank_type = 'grossing'
    	AND change_rank = 1000
    	AND created_at = '2017-11-07 00:00:00'
    	AND country = t1.country
    	AND category = t1.category
    	AND rank < t1.rank
    ) < 3;
    
    

    消耗时间: 7.260s

    1. 第二种方案
    
    SELECT
    	t1.*
    FROM
    	tb_api_app_income_rank t1
    left join  tb_api_app_income_rank t2 ON t2.created_at = '2017-11-07 00:00:00'
    AND t2.rank_type = 'grossing'
    AND t2.change_rank = 1000
    AND t1.country = t2.country
    AND t1.category = t2.category
    AND t1.rank > t2.rank
    where t1.created_at = '2017-11-07 00:00:00'
    AND t1.rank_type = 'grossing'
    AND t1.change_rank = 1000
    group by t1.country, t1.category, t1.product_id
    having count(t1.product_id)<3
    order by t1.country, t1.category,rank;
    
    

    消耗时间: 8.076s

    1. 第三种
    select * from 
    (SELECT
    	(
    		@i := CASE
    		WHEN @pre_country = country && @pre_category = category THEN
    			@i + 1
    		ELSE
    			1
    		END
    	) rownum,
    	t1.*, (@pre_country := country), (@pre_category := category)
    FROM
    	tb_api_app_income_rank t1,
    	(
    		SELECT
    			@i := 0,
    			@pre_country := '',
    			@pre_category := ''
    	) AS tmp
    WHERE
    	created_at = '2017-11-07 00:00:00'
    AND rank_type = 'grossing'
    AND change_rank = 1000
    ORDER BY
    	country,
    	category,
    	rank) t2 where t2.rownum <=3
    

    消耗时间: 0.113s

    由上得出结论,使用游标而不是连表或嵌套子查询,速度快翻几千倍

    参考资料

    1. mysql分组排序加序号(不用存储过程,就简简单单sql语句哦)
    2. mysql分组取每组前几条记录(排序)
    3. mysql分组取每组前几条记录(排名) 附group by与order by的研究
    4. SQL怎么取出每个科目前三名并按科目和分组排列
  • 相关阅读:
    oracle数据库同步
    软件设计过程中常用的几种图(一)
    面向对象建模为基础的开发模式
    常用正则表达式
    js 创建一个浮动div
    DATALIST 绑定数据分页
    ASP.NET 3.5 Extensions CTP Preview Released
    重构是一种意识流
    重构随笔: 封装集合(Encapsulate Collection)
    乱笔.................table控件,带一列合并
  • 原文地址:https://www.cnblogs.com/xunux/p/7808814.html
Copyright © 2011-2022 走看看