Select top 10 records for each category

前端 未结 14 1146
别那么骄傲
别那么骄傲 2020-11-22 04:27

I want to return top 10 records from each section in one query. Can anyone help with how to do it? Section is one of the columns in the table.

Database is SQL Serve

相关标签:
14条回答
  • 2020-11-22 05:06

    This works on SQL Server 2005 (edited to reflect your clarification):

    select *
    from Things t
    where t.ThingID in (
        select top 10 ThingID
        from Things tt
        where tt.Section = t.Section and tt.ThingDate = @Date
        order by tt.DateEntered desc
        )
        and t.ThingDate = @Date
    order by Section, DateEntered desc
    
    0 讨论(0)
  • 2020-11-22 05:06

    I know this thread is a little bit old but I've just bumped into a similar problem (select the newest article from each category) and this is the solution I came up with :

    WITH [TopCategoryArticles] AS (
        SELECT 
            [ArticleID],
            ROW_NUMBER() OVER (
                PARTITION BY [ArticleCategoryID]
                ORDER BY [ArticleDate] DESC
            ) AS [Order]
        FROM [dbo].[Articles]
    )
    SELECT [Articles].* 
    FROM 
        [TopCategoryArticles] LEFT JOIN 
        [dbo].[Articles] ON
            [TopCategoryArticles].[ArticleID] = [Articles].[ArticleID]
    WHERE [TopCategoryArticles].[Order] = 1
    

    This is very similar to Darrel's solution but overcomes the RANK problem that might return more rows than intended.

    0 讨论(0)
  • 2020-11-22 05:07

    Q) Finding TOP X records from each group(Oracle)

    SQL> select * from emp e 
      2  where e.empno in (select d.empno from emp d 
      3  where d.deptno=e.deptno and rownum<3)
      4  order by deptno
      5  ;
    
     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
    

      7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
    

    6 rows selected.


    0 讨论(0)
  • 2020-11-22 05:10
    SELECT r.*
    FROM
    (
        SELECT
            r.*,
            ROW_NUMBER() OVER(PARTITION BY r.[SectionID]
                              ORDER BY r.[DateEntered] DESC) rn
        FROM [Records] r
    ) r
    WHERE r.rn <= 10
    ORDER BY r.[DateEntered] DESC
    
    0 讨论(0)
  • 2020-11-22 05:11

    If we use SQL Server >= 2005, then we can solve the task with one select only:

    declare @t table (
        Id      int ,
        Section int,
        Moment  date
    );
    
    insert into @t values
    (   1   ,   1   , '2014-01-01'),
    (   2   ,   1   , '2014-01-02'),
    (   3   ,   1   , '2014-01-03'),
    (   4   ,   1   , '2014-01-04'),
    (   5   ,   1   , '2014-01-05'),
    
    (   6   ,   2   , '2014-02-06'),
    (   7   ,   2   , '2014-02-07'),
    (   8   ,   2   , '2014-02-08'),
    (   9   ,   2   , '2014-02-09'),
    (   10  ,   2   , '2014-02-10'),
    
    (   11  ,   3   , '2014-03-11'),
    (   12  ,   3   , '2014-03-12'),
    (   13  ,   3   , '2014-03-13'),
    (   14  ,   3   , '2014-03-14'),
    (   15  ,   3   , '2014-03-15');
    
    
    -- TWO earliest records in each Section
    
    select top 1 with ties
        Id, Section, Moment 
    from
        @t
    order by 
        case 
            when row_number() over(partition by Section order by Moment) <= 2 
            then 0 
            else 1 
        end;
    
    
    -- THREE earliest records in each Section
    
    select top 1 with ties
        Id, Section, Moment 
    from
        @t
    order by 
        case 
            when row_number() over(partition by Section order by Moment) <= 3 
            then 0 
            else 1 
        end;
    
    
    -- three LATEST records in each Section
    
    select top 1 with ties
        Id, Section, Moment 
    from
        @t
    order by 
        case 
            when row_number() over(partition by Section order by Moment desc) <= 3 
            then 0 
            else 1 
        end;
    
    0 讨论(0)
  • 2020-11-22 05:11

    Tried the following and it worked with ties too.

    SELECT rs.Field1,rs.Field2 
    FROM (
        SELECT Field1,Field2, ROW_NUMBER() 
          OVER (Partition BY Section
                ORDER BY RankCriteria DESC ) AS Rank
        FROM table
        ) rs WHERE Rank <= 10
    
    0 讨论(0)
提交回复
热议问题