Sélectionnez les lignes du haut et du bas

J'utilise SQL Server 2005 et j'essaye de réaliser quelque chose comme ceci: Je veux get les premières x lignes et les dernières x lignes dans la même instruction select.

SELECT TOP(5) BOTTOM(5) 

Bien sûr, BOTTOM n'existe pas, j'ai donc besoin d'une autre solution. Je crois qu'il existe une solution facile et élégante que je ne reçois pas. Faire à nouveau le select avec GROUP BY DESC n'est pas une option.

Utiliser un syndicat est la seule chose à laquelle je peux penser pour accomplir ceci

 select * from (select top(5) * from logins order by USERNAME ASC) a union select * from (select top(5) * from logins order by USERNAME DESC) b 

Vérifiez le lien

SQL SERVER – Comment extraire les lignes TOP et BOTTOM set à l'aide de T-SQL

Avez-vous essayé d'utiliser rownumber?

 SELECT * FROM (SELECT *, ROW_NUMBER() OVER (Order BY columnName) as TopFive ,ROW_NUMBER() OVER (Order BY columnName Desc) as BottomFive FROM Table ) WHERE TopFive <=5 or BottomFive <=5 

http://www.sqlservercurry.com/2009/02/select-top-n-and-bottom-n-rows-using.html

Je pense que vous avez deux options principales:

 SELECT TOP 5 ... FROM ... ORDER BY ... ASC UNION SELECT TOP 5 ... FROM ... ORDER BY ... DESC 

Ou, si vous connaissez le nombre d'éléments présents dans le tableau:

 SELECT ... FROM ( SELECT ..., ROW_NUMBER() OVER (ORDER BY ... ASC) AS intRow FROM ... ) AS T WHERE intRow BETWEEN 1 AND 5 OR intRow BETWEEN @Number - 5 AND @Number 

Est-ce une option pour vous d'utiliser un syndicat?

Par exemple

 select top 5 ... order by {specify columns asc} union select top 5 ... order by {specify columns desc} 

Il n'y a pas vraiment de différence entre cela et le syndicat que je connais, mais techniquement, c'est une seule requête.

 select t.* from table t where t.id in (select top 5 t2.id from table t2 order by MyColumn) or t.id in (select top 5 t2.id from table t2 order by MyColumn desc); 

Alors vous êtes dehors – faire le choix est encore la seule option, à less que vous ne vouliez tirer le jeu de résultats complet et jeter ensuite tout le rest.

Tout sql je pense peut être de la même manière – pour le fond, vous devez d'abord savoir combien d'éléments vous avez (matérialiser tout ou utiliser count (*)) ou un ordre de sorting inverse.

Désolé si cela ne vous convient pas, mais à la fin … la réalité s'en fout, et je ne vois pas d'autre moyen de le faire.

Je suppose que vous devez le faire en utilisant la sous-requête seulement

 select * from table where id in ( (SELECT id ORDER BY columnName LIMIT 5) OR (SELECT id ORDER BY columnName DESC LIMIT 5) ) select * from table where id in ( (SELECT TOP(5) id ORDER BY columnName) OR (SELECT TOP(5) id ORDER BY columnName DESC) ) 

ÉDITÉ

 select * from table where id in ( (SELECT TOP 5 id ORDER BY columnName) OR (SELECT TOP 5 id ORDER BY columnName DESC) ) 

Je devais le faire récemment pour une très grande procédure stockée; Si votre requête est assez volumineuse et que vous voulez réduire le nombre de requêtes, vous pouvez déclarer un @tempTable, insert dans ce @tempTable puis interroger à partir de ce @tempTable,

 DECLARE @tempTable TABLE ( columns.. ) INSERT INTO @tempTable VALUES ( SELECT.. your query here ..) SELECT TOP(5) columns FROM @tempTable ORDER BY column ASC -- returns first to last SELECT TOP(5) columns FROM @tempTable ORDER BY column DESC -- returns last to first