Je peux faire SELECT TOP (200) ... mais pourquoi pas BOTTOM (200)?
Bien, pour ne pas entrer dans la philosophie, comment puis-je faire l'équivalent de TOP (200) mais en sens inverse (par le bas, comme vous vous attendriez à ce que Bottom fasse ...)?
SELECT
columns
FROM
(
SELECT TOP 200
columns
FROM
My_Table
ORDER BY
a_column DESC
) SQ
ORDER BY
a_column ASC
C'est inutile. Vous pouvez utiliser un ORDER BY
et modifier simplement le tri en DESC
pour obtenir le même effet.
Désolé, mais je ne pense pas voir de réponses correctes à mon avis.
La fonction TOP
x affiche les enregistrements dans un ordre indéfini. Il découle de cette définition qu’une fonction BOTTOM
ne peut pas être définie.
Indépendant de tout index ou ordre de tri. Lorsque vous faites un ORDER BY y DESC
, vous obtenez les lignes avec la valeur y la plus élevée en premier. S'il s'agit d'un identifiant généré automatiquement, il doit afficher les derniers enregistrements ajoutés à la table, comme suggéré dans les autres réponses. Toutefois:
TOP
La réponse correcte devrait être qu'il n'y a pas, et ne peut pas, être équivalent à TOP
pour obtenir les lignes du bas.
Sélectionnez Bottom 1000 from Employee
DECLARE
@bottom int,
@count int
SET @bottom = 1000
SET @count = (select COUNT(*) from Employee)
select * from Employee emp where emp.EmployeeID not in
(
SELECT TOP (@count-@bottom) Employee.EmployeeID FROM Employee
)
La réponse actuellement acceptée par "Justin Ethier" n’est pas une réponse correcte comme l’a souligné "Protector one".
Pour autant que je sache, pour le moment, aucune autre réponse ni aucun commentaire n'apporte l'équivalent de BOTTOM (x) à la question posée par l'auteur.
Tout d'abord, considérons un scénario dans lequel cette fonctionnalité serait nécessaire:
SELECT * FROM Split('Apple,orange,banana,Apple,Lime',',')
Ceci retourne une table d'une colonne et de cinq enregistrements:
Comme vous pouvez le constater: nous n’avons pas de colonne ID; nous ne pouvons pas commander par la colonne retournée; et nous ne pouvons pas sélectionner les deux derniers enregistrements à l'aide de SQL standard comme nous pouvons le faire pour les deux premiers enregistrements.
Voici ma tentative de fournir une solution:
SELECT * INTO #mytemptable FROM Split('Apple,orange,banana,Apple,Lime',',')
ALTER TABLE #mytemptable ADD tempID INT IDENTITY
SELECT TOP 2 * FROM #mytemptable ORDER BY tempID DESC
DROP TABLE #mytemptable
Et voici une solution plus complète:
SELECT * INTO #mytemptable FROM Split('Apple,orange,banana,Apple,Lime',',')
ALTER TABLE #mytemptable ADD tempID INT IDENTITY
DELETE FROM #mytemptable WHERE tempID <= ((SELECT COUNT(*) FROM #mytemptable) - 2)
ALTER TABLE #mytemptable DROP COLUMN tempID
SELECT * FROM #mytemptable
DROP TABLE #mytemptable
Je ne prétends nullement que ce soit une bonne idée à utiliser en toutes circonstances, mais cela donne les résultats souhaités.
Tout ce que vous avez à faire est d’inverser votre ORDER BY
. Ajoutez ou supprimez DESC
.
"Tom H" la réponse ci-dessus est correcte et cela fonctionne pour moi pour obtenir les 5 derniers rangs.
SELECT [KeyCol1], [KeyCol2], [Col3]
FROM
(SELECT TOP 5 [KeyCol1],
[KeyCol2],
[Col3]
FROM [dbo].[table_name]
ORDER BY [KeyCol1],[KeyCol2] DESC) SOME_ALAIS
ORDER BY [KeyCol1],[KeyCol2] ASC
Merci.
SELECT TOP 10*from TABLE1 ORDER BY ID DESC
Où ID est la clé primaire de la TABLE1.
Le problème en ordonnant dans l'autre sens est que souvent, les indices ne sont pas utilisés. Il n’est pas non plus très extensible si vous devez sélectionner un nombre de lignes qui ne se trouvent pas au début ou à la fin. Une autre manière est la suivante.
DECLARE @NumberOfRows int;
SET @NumberOfRows = (SELECT COUNT(*) FROM TheTable);
SELECT col1, col2,...
FROM (
SELECT col1, col2,..., ROW_NUMBER() OVER (ORDER BY col1) AS intRow
FROM TheTable
) AS T
WHERE intRow > @NumberOfRows - 20;
J'ai mis au point une solution à ce problème qui ne vous oblige pas à connaître le nombre de lignes renvoyées.
Par exemple, si vous souhaitez que tous les emplacements soient consignés dans une table, à l'exception du dernier 1 (ou 2, 5 ou 34).
SELECT *
FROM
(SELECT ROW_NUMBER() OVER (ORDER BY CreatedDate) AS Row, *
FROM Locations
WHERE UserId = 12345) AS SubQuery
WHERE Row > 1 -- or 2, or 5, or 34
Commencez par créer un index dans une sous-requête en fonction de l'ordre d'origine de la table à l'aide de:
ROW_NUMBER () OVER (ORDER BY (SELECT NULL) ) AS RowIndex
Ordonnez ensuite la table par ordre décroissant selon la colonne RowIndex
que vous avez créée dans la requête principale:
ORDER BY RowIndex DESC
Et enfin, utilisez TOP
avec votre nombre de lignes souhaité:
SELECT TOP 1 * --(or 2, or 5, or 34)
FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL) ) AS RowIndex, *
FROM MyTable) AS SubQuery
ORDER BY RowIndex DESC
L'astuce consiste à interroger une simple sous-requête triée par ordre décroissant, suivie d'un tri croissant sur la même colonne.
SELECT * FROM
(SELECT TOP 200 * FROM [table] t2 ORDER BY t2.[column] DESC) t1
ORDER BY t1.[column]
essaye ça.
declare @floor int --this is the offset from the bottom, the number of results to exclude
declare @resultLimit int --the number of results actually retrieved for use
declare @total int --just adds them up, the total number of results fetched initially
--following is for gathering top 60 results total, then getting rid of top 50. We only keep the last 10
set @floor = 50
set @resultLimit = 10
set @total = @floor + @resultLimit
declare @tmp0 table(
--table body
)
declare @tmp1 table(
--table body
)
--this line will drop the wanted results from whatever table we're selecting from
insert into @tmp0
select Top @total --what to select (the where, from, etc)
--using floor, insert the part we don't want into the second tmp table
insert into @tmp1
select top @floor * from @tmp0
--using select except, exclude top x results from the query
select * from @tmp0
except
select * from @tmp1