Prendre la deuxième rangée en dernier avec un seul choix dans SQL Server?

J'essayais de sélectionner la deuxième rangée avec SQL Server. J'ai donc écrit une requête comme celle-ci:

SELECT TOP 1 * From Cinema WHERE CinemaID!=(SELECT TOP 1 CinemaID FROM Cinema ORDER BY CinemaID DESC) ORDER BY CinemaID DESC 

et il a fait ce dont j'avais besoin. Mais je veux faire la même chose avec un seul choix.

J'ai lu que la clause LIMIT dans MySQL le fait. Mais je n'ai pas pu find d'équivalent de ça. J'apprécie donc toute aide pour find quelque chose d'utile.

Pour get la 2e rangée en une, select:

 SELECT TOP 1 * From (select Top 2 * from Cinema ORDER BY CinemaID DESC) x ORDER BY CinemaID 

C'est vraiment seulement "un" select car le select externe est sur seulement 2 lignes.

La meilleure façon de le faire (et compatible avec la norme ANSI SQL) est d'utiliser une CTE (Common Table Expression) avec la fonction ROW_NUMBER :

 ;WITH OrderedCinemas AS ( SELECT CinemaID, CinemaName, ROW_NUMBER() OVER(ORDER BY CinemaID DESC) AS 'RowNum' FROM dbo.Cinema ) SELECT CinemaID, CinemaName FROM OrderedCinemas WHERE RowNum = 2 

En utilisant cette construction, vous pouvez get la deuxième valeur la plus élevée très facilement – ou la cinquième plus WHERE RowNum = 5 ( WHERE RowNum = 5 ) ou les trois premières lignes ( WHERE RowNum <= 3 ) ou tout ce dont vous avez besoin – les valeurs CinemaID sont simplement ordonnées et séquentiellement numéroté pour votre usage.

Ce qui suit ne fonctionne pas, expliquant pourquoi: Utilisation de la colonne dérivée de la fonction de classment dans la clause where (SQL Server 2008)

Je vais le garder ici pour être complet:


 SELECT row_number() OVER (ORDER BY col) r, * FROM tbl WHERE r = 2 

Plus d'infos: http://www.bidn.com/blogs/marcoadf/bidn-blog/379/ranking-functions-row_number-vs-rank-vs-dense_rank-vs-ntile


Donc je pense que la façon la plus lisible de le faire est:

 SELECT * FROM (SELECT row_number() OVER (ORDER BY col) r, * FROM tbl) q WHERE r = 2 

Comme cette (ancienne) question n'a pas été étiquetée avec une version SQL-Server spécifique et aucune (très bonne) réponse n'utilise qu'une seule clause SELECT – pour la bonne raison que ce n'était pas possible dans les anciennes versions – en voici une qui fonctionne seulement dans les versions récentes, 2012+:

 SELECT c.* FROM dbo.Cinema AS c ORDER BY CinemaID DESC OFFSET 1 ROW FETCH FIRST 1 ROW ONLY ; 

Testé à SQLFiddle

 SELECT TOP 1 * FROM tbl_CompanyMaster where Companyid >= (SELECT MAX(Companyid) - 1 FROM tbl_CompanyMaster) 

Donc, dans l'esprit d'utiliser seulement une clause SELECT comme indiqué dans le PO et en abusant complètement de T-SQL en général, je propose quelque chose que je ne reorderais jamais, jamais en utilisant dans la production qui satisfait néanless les critères énoncés:

 update Cinema set Cinema.SomeField = Cinema.SomeField output inserted.* from Cinema inner join ( select top 2 CinemaID, ROW_NUMBER() over (order by CinemaID desc) as RowNum from Cinema ) rsRowNum on rsRowNum.CinemaID = Cinema.CinemaID where RowNum = 2 

Cette requête fonctionnera aussi pour SQLITE

 SELECT * From (select * from Cinema ORDER BY CinemaID DESC LIMIT 2) AS name ORDER BY CinemaID LIMIT 1 

Vous n'utilisez qu'une seule instruction SELECT. Une instruction SELECT peut inclure un nombre arbitraire (plus ou less) de sous-requêtes (sous-requêtes corrélées, sous-requêtes scalaires, etc.), chacune avec sa propre clause SELECT. Mais ce n'est toujours qu'une seule instruction SELECT.

Si vous souhaitez éviter une sous-requête, vous pouvez sélectionner le top 2 et ignorer celui que vous ne voulez pas. Ce genre de programmation est plutôt fragile, cependant. Vous devez vous callbacker de quoi sauter chaque fois; tôt ou tard, vous oublierez.

Deux sélections mais un peu plus rapide

 select top 1 * from( SELECT TOP 2 * From Cinema WHERE CinemaID ORDER BY CinemaID DESC) top2 Order by CinemaID 
 SELECT field_name FROM (SELECT TOP 2 field_name FROM table_name ORDER BY field_name DESC) WHERE rownum = 2; 
 select * from TABLE_NAME order by COLUMN_NAME desc limit 1,1 ; 

COLUMN_NAME doit être "key primaire" ou "Unique"

 select top 1* from(SELECT TOP 2 * From Cinema WHERE CinemaID ORDER BY CinemaID DESC) XYZ ORDER BY CinemaID 

où XYZ n'est pas un mot-key. C'est juste un mot. Et le mot peut être n'importe quoi.

Si vous avez besoin de faire cela, mais:

  • la colonne est différente de l' id
  • vous devez order par une colonne spécifique
  • ne peut pas utiliser la clause SELECT on FROM (si vous utilisez d'anciennes versions d'Hibernate, par exemple).

Tu peux faire:

 select top 1 * from Cinema where date < (select MAX(date) from Cinema) order by date desc 

Le moyen le plus simple d'get la deuxième ligne de la table sql est: user ORDER BY CinemaID DESC et définir LIMIT 1,1

ESSAYE ÇA

 SELECT * from `Cinema` ORDER BY `CinemaID` DESC LIMIT 1,1