247

1 つのクエリで各セクションから上位 10 件のレコードを返したいと考えています。誰でもそれを行う方法を手伝ってもらえますか? セクションは、テーブル内の列の 1 つです。

データベースは SQL Server 2005 です。入力した日付の上位 10 件を返したいと考えています。セクションは、ビジネス、ローカル、および機能です。ある特定の日付について、上位 (10) のビジネス行 (最新のエントリ)、上位 (10) のローカル行、および上位 (10) の機能のみが必要です。

4

14 に答える 14

255

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 のソリューションが適している可能性があります。

于 2008-10-07T02:13:52.423 に答える
114

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
于 2012-06-25T10:16:59.370 に答える
42
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
于 2012-06-15T14:26:32.557 に答える
35

これは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
于 2008-10-07T02:09:02.107 に答える
20

私はこのようにします:

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 にも含まれている必要があります。

于 2008-10-07T04:07:06.453 に答える
18

SQL Server >= 2005 を使用する場合、1 つの選択のみでタスクを解決できます。

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;
于 2014-12-26T15:05:26.147 に答える
10

セクションが何であるかがわかっている場合は、次のことができます。

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
于 2008-10-07T02:10:05.113 に答える
9

このスレッドが少し古いことは知っていますが、同様の問題に遭遇したばかりです(各カテゴリから最新の記事を選択してください)。これが私が思いついた解決策です:

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

これは Darrel のソリューションと非常に似ていますが、意図したよりも多くの行を返す可能性がある RANK 問題を克服しています。

于 2011-02-14T12:10:18.583 に答える
6

Q) 各グループからTOP Xレコードを探す(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 行が選択されました。


于 2011-02-20T17:36:30.367 に答える
4

UNION演算子は役に立ちますか? セクションごとに 1 つの SELECT を用意してから、それらを一緒に UNION します。ただし、固定数のセクションでのみ機能すると思います。

于 2008-10-07T02:05:28.633 に答える
1

このアプローチを試すことができます。このクエリは、国ごとに最も人口の多い 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;
于 2017-01-25T22:41:16.930 に答える