zoukankan      html  css  js  c++  java
  • SQL中Group分组获取Top N 方法实现

    有产品表,包含id,name,city,addtime四个字段,因报表需要按城市分组,统计每个城市的最新10个产品,便向该表中插入了100万数据,做了如下系列测试:

    CREATE TABLE [dbo].[products](
        [id] [int] IDENTITY(1,1) NOT NULL,
        [name] [nvarchar](50) NULL,
        [addtime] [datetime] NULL,
        [city] [nvarchar](10) NULL,
     CONSTRAINT [PK_products] PRIMARY KEY CLUSTERED 
    (
        [id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    1、采用row_number方法,执行5次,平均下来8秒左右,速度最快。

    select no, id,name,city 
    from  (select  no =row_number() over (partition by city order by addtime desc), * from products)t
    where no< 11 order by city asc,addtime desc

    2、采用cross apply方法,执行了3次,基本都在3分5秒以上,已经很慢了。

    select distinct b.id,b.name,b.city from products a 
    cross apply (select top 10 * from products where city = a.city order by  addtime desc) b

    3、采用Count查询,只执行了两次,第一次执行到5分钟时,取消任务执行了;第二次执行到13分钟时,没有hold住又直接停止了,实在无法忍受。

    select id,name,city from products a 
    where (  select count(city) from products where a.city = city and addtime>a.addtime) < 10
    order by city asc,addtime desc

    4、采用游标方法,这个最后测试的,执行了5次,每次都是10秒完成,感觉还不错。

    declare @city nvarchar(10)
    create table #Top(id int,name nvarchar(50),city nvarchar(10),addtime datetime)
    declare mycursor cursor for
    select  distinct city from products order by city asc
    open mycursor
    fetch next from mycursor into @city
    while @@fetch_status =0
    begin
        insert into #Top 
        select top 10 id,name,city,addtime from products where city = @city 
        fetch next from mycursor into @city
    end 
    close mycursor
    deallocate mycursor
    Select * from #Top order by city asc,addtime desc
    drop table #Top

    通过上述对比不难发现,在面临Group获取Top N场景时,可以首选row_number,游标cursor其次,另外两个就基本不考虑了,数据量大的时候根本没法使用。

  • 相关阅读:
    poj 3528 (三维几何求凸包+凸包表面积)
    dijkstra模板(好像是斐波那契额堆优化,但我为什么看起来像优先队列优化,和spfa一样)
    最大空凸包模板
    ICPC 2017–2018, NEERC, Northern Subregional Contest St Petersburg, November 4, 2017 I题
    hdu 5248 序列变换
    hdu 2063(二分图模板测试)
    组合数
    85. Maximal Rectangle 由1拼出的最大矩形
    750. Number Of Corner Rectangles四周是点的矩形个数
    801. Minimum Swaps To Make Sequences Increasing 为使两个数组严格递增,所需要的最小交换次数
  • 原文地址:https://www.cnblogs.com/qxfan/p/2952039.html
Copyright © 2011-2022 走看看