275 votes

sélectionner les 10 meilleurs enregistrements pour chaque catégorie

Je souhaite renvoyer les 10 meilleurs enregistrements de chaque section de la requête. Quelqu'un peut-il aider à le faire. Section est l'une des colonnes du tableau.

La base de données est SQL Server 2005. Top 10 par date saisie. Les sections sont affaires, locales et caractéristiques. Pour une date donnée, je ne souhaite utiliser que les 10 premières lignes commerciales (entrée la plus récente), les 10 premières lignes locales et les 10 principales caractéristiques pour une date donnée.

272voto

Darrel Miller Points 56797

Si vous utilisez SQL 2005, vous pouvez faire quelque chose comme ça ...

 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
 

Si votre RankCriteria a des liens, vous pouvez renvoyer plus de 10 lignes et la solution de Matt peut être meilleure pour vous.

122voto

Phil Rabbitt Points 131

Dans T-SQL, je ferais:

 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
 

35voto

Matt Hamilton Points 98268

Cela fonctionne sur SQL Server 2005 (modifié pour refléter votre 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
 

19voto

Bill Karwin Points 204877

Je le fais de cette façon:

 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;
 

update: Cet exemple de GROUP BY fonctionne uniquement avec MySQL et SQLite, car ces bases de données sont plus permissives que SQL standard en ce qui concerne GROUP BY. La plupart des implémentations SQL exigent que toutes les colonnes de la liste de sélection qui ne font pas partie d'une expression d'agrégat figurent également dans GROUP BY.

15voto

Blorgbeard Points 38991

Si vous connaissez les sections, vous pouvez faire:

 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
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X