2008-10-07 67 views
142

我想在一個查詢中返回每個部分的前10條記錄。任何人都可以幫助如何做到這一點?部分是表中的一列。爲每個類別選擇前10條記錄

數據庫是SQL Server 2005.我想按輸入日期返回前10位。部分是商業,本地和功能。對於某個特定日期,我只需要頂部(10)業務行(最新條目),頂部(10)本地行和頂部(10)功能。

+0

這些答案有幫助嗎? – 2017-12-01 20:55:58

回答

4

可能是UNION運營商爲您工作?每個部分都有一個SELECT,然後將它們聯合在一起。猜猜它只能用於固定數量的部分。

28

這工作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 
+2

但是,對於Section爲空的行,這不起作用。你需要說「哪裏(tt.Section爲空,t.Section爲空)或tt.Section = t.Section」 – 2008-10-07 02:11:30

9

如果你知道是什麼部分是,你可以這樣做:

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 
+3

這將是最簡單的方法。 – 2008-10-07 02:15:33

+1

但是,如果您有150個類別,或者如果類別按日,周等變化,這將是低效的。 – 2017-09-08 15:26:03

+0

當然,但是引用OP:「部分是業務,本地和功能」。如果你有三個靜態類別,這是最好的方式。 – Blorgbeard 2017-09-08 15:31:08

166

如果您正在使用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有關係,那麼你可能會返回超過1 0行和馬特的解決方案可能對你更好。

+25

如果您真的只想要前10名,請將其更改爲RowNumber()而不是Rank()。沒有關係。 – 2008-10-07 03:26:04

+3

這是有效的,但請注意,如果沒有* first * key是RankCriteria的索引,rank()可能會被查詢規劃器轉換爲整個表的排序。在這種情況下,您可以選擇不同的部分並交叉申請挑選RankCriteria desc訂購的前10名。 – 2013-02-13 09:42:24

+0

偉大的答案!幾乎正是我所需要的。我結束了`DENSE_RANK`的編號沒有任何差距。 +1 – 2013-03-21 23:33:55

15

我做這種方式:

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; 

更新: BY在MySQL和SQLite的唯一作品本組的例子,因爲這些數據庫是不是把GROUP BY標準SQL更加寬容。大多數SQL實現要求選擇列表中不屬於聚合表達式的所有列也位於GROUP BY中。

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 

這與Darrel的解決方案非常相似,但克服了RANK問題,可能會返回比預期更多的行。

4

Q)從每個組(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行查找TOP X記錄。


18
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 
57

在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

如果你想製作的部分進行分組輸出,從每一節像這樣只顯示前ñ記錄:

SECTION  SUBSECTION 

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

...那麼以下內容應該適用於所有SQL數據庫。如果您想要前10名,只需將2更改爲10即可。

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'; 
5

如果我們使用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; 
0

你可以試試這種方法。 此查詢返回每個國家/地區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; 
2

試過以下,它也用於關係。

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 
相關問題