web-dev-qa-db-fra.com

Comment sélectionner les 5 dernières lignes d'un tableau sans trier?

Je souhaite sélectionner les 5 derniers enregistrements d'une table dans SQL Server sans les disposer en ordre croissant ou décroissant.

23
ganesh Verma

C’est à peu près la requête la plus bizarre que j’ai jamais écrite, mais je suis presque certaine qu’elle obtient les "5 dernières" lignes d’une table sans ordre:

select * 
from issues
where issueid not in (
    select top (
        (select count(*) from issues) - 5
    ) issueid
    from issues
)

Notez que cela utilise la capacité de SQL Server 2005 à transmettre une valeur dans la clause "top" - cela ne fonctionne pas sur SQL Server 2000.

34
Matt Hamilton

Supposons que vous ayez un index sur id, ce sera très rapide:

SELECT * FROM [MyTable] WHERE [id] > (SELECT MAX([id]) - 5 FROM [MyTable])
27
msuvajac
  1. Vous devez compter le nombre de lignes dans la table (disons que nous avons 12 lignes)
  2. puis soustrayez 5 lignes (nous sommes maintenant en 7)
  3. sélectionnez * où index_column> 7 

    select * from users
    where user_id > 
    ( (select COUNT(*) from users) - 5)
    

    vous pouvez les commander ASC ou DESC

    Mais en utilisant ce code

    select TOP 5 from users order by user_id DESC
    

    il ne sera pas commandé facilement.

10
M.M.F

La formulation de votre question donne l’impression que vous pensez que vous devez utiliser physiquement les données du tableau afin de les récupérer dans l’ordre que vous souhaitez. Si tel est le cas, la clause ORDER BY existe à cet effet. L'ordre physique dans lequel les enregistrements sont stockés reste inchangé lors de l'utilisation de ORDER BY. Les enregistrements sont triés en mémoire (ou dans un espace disque temporaire) avant d’être renvoyés.

Notez que l'ordre dans lequel les enregistrements sont renvoyés n'est pas garanti sans l'utilisation d'une clause ORDER BY. Ainsi, bien que l'une des suggestions présentées puisse fonctionner, il n'y a aucune raison de penser qu'elles continueront à fonctionner, pas plus que vous ne pouvez prouver qu'elles fonctionnent dans tous les cas avec votre base de données actuelle. Ceci est inhérent à la conception - je suppose qu’il s’agit de donner au moteur de base de données la liberté de procéder comme il le fera avec les enregistrements afin d’optimiser les performances dans les cas où aucun ordre explicite n’est spécifié.

En supposant que vous souhaitiez que les 5 derniers enregistrements soient triés par le champ Nom par ordre croissant, vous pouvez effectuer quelque chose comme ceci, qui devrait fonctionner dans SQL 2000 ou 2005:

select Name 
from (
    select top 5 Name 
    from MyTable 
    order by Name desc
) a 
order by Name asc
10
RedFilter

Vous pouvez utiliser ceci dans 5 enregistrements des derniers enregistrements,

SELECT *
FROM   Table Name
WHERE  ID <= IDENT_CURRENT('Table Name')
AND ID >= IDENT_CURRENT('Table Name') - 5
4
Nadia Deqmin

Sans commande, c'est impossible. Qu'est-ce qui définit le "fond"? Ce qui suit sélectionnera 5 lignes en fonction de la manière dont elles sont stockées dans la base de données.

SELECT TOP 5 * FROM [TableName]

3
Stefan Mai

Eh bien, les "cinq dernières lignes" sont en réalité les cinq dernières lignes en fonction de votre index clusterisé. Votre index clusterisé, par définition, est la façon dont les lignes sont ordonnées. Donc, vous ne pouvez vraiment pas obtenir les "cinq dernières lignes" sans ordre. Vous pouvez toutefois obtenir les cinq dernières lignes relatives à l'index clusterisé.

SELECT TOP 5 * FROM MyTable
ORDER BY MyCLusteredIndexColumn1, MyCLusteredIndexColumnq, ..., MyCLusteredIndexColumnN DESC
3
Charles Graham
select * from table limit 5 offset (select count(*) from table) - 5;
2
Rob

Dans SQL Server 2012, vous pouvez procéder comme suit:

Declare @Count1 int ;

Select @Count1 = Count(*)
FROM    [Log] AS L

SELECT  
   *
FROM    [Log] AS L
ORDER BY L.id
OFFSET @Count - 5 ROWS
FETCH NEXT 5 ROWS ONLY;
2
Ardalan Shahgholi

5 dernières lignes récupérées dans mysql


Cette requête fonctionne parfaitement

SELECT * FROM (SELECT * FROM recharge ORDER BY sno DESC LIMIT 5)sub ORDER BY sno ASC

ou

select sno from(select sno from recharge order by sno desc limit 5) as t where t.sno order by t.sno asc
2
M Palani Mca

Si vous savez le nombre total de lignes, vous pouvez utiliser la fonction ROW_NUMBER () . Voici un exemple de MSDN ( http://msdn.Microsoft.com/en-us/library/ms186734.aspx )

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;
2
idstam

Essayez ceci si vous n'avez pas de clé primaire ou de colonne identique:

select [Stu_Id],[Student_Name] ,[City] ,[Registered], 
       RowNum = row_number() OVER (ORDER BY (SELECT 0))    
from student
ORDER BY RowNum desc 
2
Apps Tawale

Vous pouvez les récupérer de la mémoire.
Donc, vous obtenez d’abord les lignes dans un DataSet, puis les 5 derniers du DataSet.

1
eddy147

Il existe un truc pratique qui fonctionne dans certaines bases de données pour commander en ordre de base de données, 

SELECT * FROM TableName ORDER BY true

Apparemment, cela peut fonctionner conjointement avec l'une des autres suggestions publiées ici pour laisser les résultats dans l'ordre "dans l'ordre dans lequel ils sont sortis de la base de données", ordre dans lequel ils ont été modifiés pour la dernière fois 

1
Kent Fredric

Lorsque le nombre de lignes dans la table est inférieur à 5, les réponses de Matt Hamilton et de msuvajac sont incorrectes .Parce qu'une valeur de nombre de lignes TOP N peut ne pas être négative.
Un bon exemple peut être trouvé Ici .

1
Ali Sohrabi
select * 
from table 
order by empno(primary key) desc 
fetch first 5 rows only
1
Shrabani Joarder

j'utilise ce code:

select * from tweets where placeID = '$placeID' and id > (
    (select count(*) from tweets where placeID = '$placeID')-2)
1
user3236289
DECLARE @MYVAR  NVARCHAR(100)
DECLARE @step  int
SET @step = 0;


DECLARE MYTESTCURSOR CURSOR
DYNAMIC 
FOR
SELECT col FROM [dbo].[table]
OPEN MYTESTCURSOR
FETCH LAST FROM MYTESTCURSOR INTO @MYVAR
print @MYVAR;


WHILE @step < 10
BEGIN   
    FETCH PRIOR FROM MYTESTCURSOR INTO @MYVAR
        print @MYVAR;
        SET @step = @step + 1;
END   
CLOSE MYTESTCURSOR
DEALLOCATE MYTESTCURSOR
0
Slava

Merci à @Apps Tawale , D'après sa réponse , voici un peu d'une autre version (ma), 

Pour sélectionner les 5 derniers enregistrements sans colonne d'identité, 

select top 5 *, 
   RowNum = row_number() OVER (ORDER BY (SELECT 0))    
from  [dbo].[ViewEmployeeMaster]
ORDER BY RowNum desc

Néanmoins, il a une commande par, mais sur RowNum :)

Note (1): la requête ci-dessus inverse l'ordre de ce que nous obtenons lorsque nous exécutons la requête select principale.

Donc, pour maintenir l'ordre, nous pouvons légèrement aller comme:

select *, RowNum2 = row_number() OVER (ORDER BY (SELECT 0))    
from ( 
        select top 5 *, RowNum = row_number() OVER (ORDER BY (SELECT 0))    
        from  [dbo].[ViewEmployeeMaster]
        ORDER BY RowNum desc
     ) as t1
order by RowNum2 desc

Note (2): Sans colonne d'identité, la requête prend un peu de temps en cas de données volumineuses.

0
Irf