복붙노트

[SQL] 각 범주에 대한 상위 10 개의 레코드를 선택

SQL

각 범주에 대한 상위 10 개의 레코드를 선택

나는 한 쿼리에서 각 섹션에서 상위 10 개 레코드를 반환하고자합니다. 그것을 수행하는 방법과 캔 사람의 도움? 절은 테이블의 열 중 하나입니다.

데이터베이스 내가 입력 한 날짜를 기준으로 상위 10를 반환 할 SQL 서버 2005입니다. 섹션 사업, 지역 및 기능입니다. 하나의 특정 날짜 난 단지 상단 (10) 비즈니스 행 (가장 최근 항목), 상부 (10) 지역 행 상단을 원하는 (10)이 있습니다.

해결법

  1. ==============================

    1.당신은 SQL 2005를 사용하는 경우 당신은 이런 식으로 뭔가를 할 수 있습니다 ...

    당신은 SQL 2005를 사용하는 경우 당신은 이런 식으로 뭔가를 할 수 있습니다 ...

    SELECT rs.Field1,rs.Field2 
        FROM (
            SELECT Field1,Field2, Rank() 
              over (Partition BY Section
                    ORDER BY RankCriteria DESC ) AS Rank
            FROM table
            ) rs WHERE Rank <= 10
    

    당신의 RankCriteria이 관계를 가지고 있다면 당신은 10 개 이상의 행을 반환 할 수 있습니다와 매트의 솔루션은 당신을 위해 더 좋을 수 있습니다.

  2. ==============================

    2.T-SQL, 나는 할 것이다 :

    T-SQL, 나는 할 것이다 :

    WITH TOPTEN AS (
        SELECT *, ROW_NUMBER() 
        over (
            PARTITION BY [group_by_field] 
            order by [prioritise_field]
        ) AS RowNo 
        FROM [table_name]
    )
    SELECT * FROM TOPTEN WHERE RowNo <= 10
    
  3. ==============================

    3.SQL 서버 2005이 작품은 (당신의 설명을 반영하기 위해 편집) :

    SQL 서버 2005이 작품은 (당신의 설명을 반영하기 위해 편집) :

    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
    
  4. ==============================

    4.

    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
    
  5. ==============================

    5.나는이 방법을 수행합니다

    나는이 방법을 수행합니다

    SELECT a.* FROM articles AS a
      LEFT JOIN articles AS a2 
        ON a.section = a2.section AND a.article_date <= a2.article_date
    GROUP BY a.article_id
    HAVING COUNT(*) <= 10;
    

    업데이트 : GROUP BY의 예는 MySQL과 만 SQLite는 작동, 그 데이터베이스가 GROUP BY에 대한 표준 SQL보다 더 관대 때문이다. 대부분의 SQL 구현은 집계 표현의 일부가 아닌 선택 목록의 모든 열이 GROUP BY에 또한 할 것을 요구하고 있습니다.

  6. ==============================

    6.우리는 하나는 선택과 SQL 서버> = 2005, 우리가 작업을 해결할 수 사용하는 경우 :

    우리는 하나는 선택과 SQL 서버> = 2005, 우리가 작업을 해결할 수 사용하는 경우 :

    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;
    
  7. ==============================

    7.이 부분이 무엇인지 알고 있다면, 당신은 할 수 있습니다 :

    이 부분이 무엇인지 알고 있다면, 당신은 할 수 있습니다 :

    select top 10 * from table where section=1
    union
    select top 10 * from table where section=2
    union
    select top 10 * from table where section=3
    
  8. ==============================

    8.나는이 스레드가 조금 오래지만 난 그냥 비슷한 문제 (각 카테고리의 최신 기사를 선택)에 충돌했고 이것이 내가 생각 해낸 해결책을 알고 :

    나는이 스레드가 조금 오래지만 난 그냥 비슷한 문제 (각 카테고리의 최신 기사를 선택)에 충돌했고 이것이 내가 생각 해낸 해결책을 알고 :

    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
    

    이 대럴의 솔루션과 매우 유사하지만, 의도 한 것보다 더 많은 행을 반환 할 수있는 RANK 문제를 극복한다.

  9. ==============================

    9.다음을 시도하고 너무 타이로했다.

    다음을 시도하고 너무 타이로했다.

    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
    
  10. ==============================

    10.당신을위한 UNION 연산자 작업은 수 있는가? 각 섹션에 대해 하나의 SELECT를 가지고, 다음 UNION 그들을 함께. 단지 생각 섹션의 고정 번호 일하는 것이 그것을 추측.

    당신을위한 UNION 연산자 작업은 수 있는가? 각 섹션에 대해 하나의 SELECT를 가지고, 다음 UNION 그들을 함께. 단지 생각 섹션의 고정 번호 일하는 것이 그것을 추측.

  11. ==============================

    11.이 같은 각 섹션 뭔가 만 상위 n 개의 기록을 표시하는 섹션별로 그룹화 출력을 생성하려면 :

    이 같은 각 섹션 뭔가 만 상위 n 개의 기록을 표시하는 섹션별로 그룹화 출력을 생성하려면 :

    SECTION     SUBSECTION
    
    deer        American Elk/Wapiti
    deer        Chinese Water Deer
    dog         Cocker Spaniel
    dog         German Shephard
    horse       Appaloosa
    horse       Morgan
    

    ... 그 다음은 모든 SQL 데이터베이스와 꽤 일반적으로 작동합니다. 당신이 상위 10를 원한다면, 단지 쿼리의 끝으로 10에 2를 변경합니다.

    select
        x1.section
        , x1.subsection
    from example x1
    where
        (
        select count(*)
        from example x2
        where x2.section = x1.section
        and x2.subsection <= x1.subsection
        ) <= 2
    order by section, subsection;
    

    설정하기:

    create table example ( id int, section varchar(25), subsection varchar(25) );
    
    insert into example select 0, 'dog', 'Labrador Retriever';
    insert into example select 1, 'deer', 'Whitetail';
    insert into example select 2, 'horse', 'Morgan';
    insert into example select 3, 'horse', 'Tarpan';
    insert into example select 4, 'deer', 'Row';
    insert into example select 5, 'horse', 'Appaloosa';
    insert into example select 6, 'dog', 'German Shephard';
    insert into example select 7, 'horse', 'Thoroughbred';
    insert into example select 8, 'dog', 'Mutt';
    insert into example select 9, 'horse', 'Welara Pony';
    insert into example select 10, 'dog', 'Cocker Spaniel';
    insert into example select 11, 'deer', 'American Elk/Wapiti';
    insert into example select 12, 'horse', 'Shetland Pony';
    insert into example select 13, 'deer', 'Chinese Water Deer';
    insert into example select 14, 'deer', 'Fallow';
    
  12. ==============================

    12.Q) 각 그룹에서 찾기 TOP X 기록 (오라클)

    Q) 각 그룹에서 찾기 TOP X 기록 (오라클)

    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 행 선택.

  13. ==============================

    13.문제는 SQL 서버 2005에 대한 동안, 대부분의 사람들은에 이동하고 그들이이 문제를 발견 할 경우, 어떤 다른 상황에서 선호하는 해답이 될 수있는이 블로그 게시물에 도시 된 바와 같이 CROSS APPLY를 사용하여 하나입니다.

    문제는 SQL 서버 2005에 대한 동안, 대부분의 사람들은에 이동하고 그들이이 문제를 발견 할 경우, 어떤 다른 상황에서 선호하는 해답이 될 수있는이 블로그 게시물에 도시 된 바와 같이 CROSS APPLY를 사용하여 하나입니다.

    SELECT *
    FROM t
    CROSS APPLY (
      SELECT TOP 10 u.*
      FROM u
      WHERE u.t_id = t.t_id
      ORDER BY u.something DESC
    ) u
    

    이 쿼리는 두 테이블을 포함한다. 영업 이익의 쿼리는 윈도우 함수 기반 솔루션보다 효율적으로 될 수있는 경우에, 1 표를 포함한다.

  14. ==============================

    14.이 접근 방법을 시도 할 수 있습니다. 이 쿼리 반환 각 국가의 10 개 가장 인구가 많은 도시.

    이 접근 방법을 시도 할 수 있습니다. 이 쿼리 반환 각 국가의 10 개 가장 인구가 많은 도시.

       SELECT city, country, population
       FROM
       (SELECT city, country, population, 
       @country_rank := IF(@current_country = country, @country_rank + 1, 1) AS country_rank,
       @current_country := country 
       FROM cities
       ORDER BY country, population DESC
       ) ranked
       WHERE country_rank <= 10;
    
  15. from https://stackoverflow.com/questions/176964/select-top-10-records-for-each-category by cc-by-sa and MIT license