[sql] 각 카테고리마다 상위 10 개 레코드를 선택하십시오.

하나의 쿼리로 각 섹션에서 상위 10 개의 레코드를 반환하고 싶습니다. 누구나 그것을하는 방법을 도울 수 있습니까? 섹션은 테이블의 열 중 하나입니다.

데이터베이스는 SQL Server 2005입니다. 입력 한 날짜별로 상위 10 개를 반환하려고합니다. 섹션은 비즈니스, 지역 및 기능입니다. 특정 날짜의 경우 상위 10 개 비즈니스 행 (가장 최근 항목), 상위 10 개 로컬 행 및 상위 10 개 기능 만 원합니다.



답변

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 개가 넘는 행을 반환 할 수 있으며 Matt의 솔루션이 더 나을 수 있습니다.


답변

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


답변

이것은 SQL Server 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


답변

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


답변

나는 이것을 이렇게한다 :

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에 있어야합니다.


답변

SQL Server> = 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;


답변

섹션이 무엇인지 아는 경우 다음을 수행 할 수 있습니다.

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