Je suis intéressé à apprendre quelques méthodes (idéalement) indépendantes de la base de données pour sélectionner la n ème ligne dans une table de base de données. Il serait également intéressant de voir comment cela peut être réalisé en utilisant la fonctionnalité native des bases de données suivantes:
- serveur SQL
- MySQL
- PostgreSQL
- SQLite
- Oracle
Je fais actuellement quelque chose comme ce qui suit dans SQL Server 2005, mais je serais intéressé à voir d'autres approches plus agnostiques:
WITH Ordered AS (
SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS RowNumber, OrderID, OrderDate
FROM Orders)
SELECT *
FROM Ordered
WHERE RowNumber = 1000000
Crédit pour le SQL ci-dessus: le blog de Firoz Ansari
Mise à jour: voir la réponse de Troels Arvin concernant la norme SQL. Troels, avez-vous des liens que nous pouvons citer?
OrderNo N
, introduisez une colonne OrderSequenceNo dans le tableau et générez-la à partir d'un générateur de séquence indépendant lors de la création d'une nouvelle commande.offset x fetch first y rows only
. Actuellement pris en charge par (au moins) Postgres, Oracle12, DB2.Réponses:
Il existe des moyens de le faire dans des parties facultatives de la norme, mais de nombreuses bases de données prennent en charge leur propre façon de le faire.
Un très bon site qui parle de cela et d'autres choses est http://troels.arvin.dk/db/rdbms/#select-limit .
Fondamentalement, PostgreSQL et MySQL prennent en charge le non standard:
Oracle, DB2 et MSSQL prennent en charge les fonctions de fenêtrage standard:
(que je viens de copier du site lié ci-dessus car je n'utilise jamais ces bases de données)
Mise à jour: à partir de PostgreSQL 8.4, les fonctions de fenêtrage standard sont prises en charge, alors attendez-vous à ce que le deuxième exemple fonctionne également pour PostgreSQL.
Mise à jour: SQLite a ajouté la prise en charge des fonctions de fenêtre dans la version 3.25.0 le 2018-09-15 afin que les deux formulaires fonctionnent également dans SQLite.
la source
WHERE rownumber = n
uniquement pour obtenir la nième ligne?PostgreSQL prend en charge les fonctions de fenêtrage telles que définies par la norme SQL, mais elles sont maladroites, donc la plupart des gens utilisent (la non standard)
LIMIT
/OFFSET
:Cet exemple sélectionne la 21e ligne.
OFFSET 20
demande à Postgres de sauter les 20 premiers enregistrements. Si vous ne spécifiez pas deORDER BY
clause, rien ne garantit quel enregistrement vous récupérerez, ce qui est rarement utile.la source
Je ne suis pas sûr de tout le reste, mais je sais que SQLite et MySQL n'ont aucun ordre de ligne "par défaut". Dans ces deux dialectes, au moins, l'extrait de code suivant saisit la 15e entrée de the_table, en triant par date / heure à laquelle il a été ajouté:
(bien sûr, vous devez avoir un champ DATETIME ajouté et le définir à la date / heure à laquelle l'entrée a été ajoutée ...)
la source
SQL 2005 et versions ultérieures ont cette fonctionnalité intégrée. Utilisez la fonction ROW_NUMBER (). Il est excellent pour les pages Web avec une navigation de style << Précédente et Suivante >>:
Syntaxe:
la source
Je soupçonne que c'est extrêmement inefficace mais c'est une approche assez simple, qui a fonctionné sur un petit ensemble de données sur lequel je l'ai essayé.
Cela obtiendrait le 5ème élément, changer le deuxième numéro supérieur pour obtenir un nième élément différent
Serveur SQL uniquement (je pense) mais devrait fonctionner sur les anciennes versions qui ne prennent pas en charge ROW_NUMBER ().
la source
1 petit changement: n-1 au lieu de n.
la source
Vérifiez-le sur SQL Server:
Cela vous donnera le 10ème rang de table emp!
la source
Contrairement à ce que prétendent certaines réponses, le standard SQL n'est pas muet sur ce sujet.
Depuis SQL: 2003, vous pouvez utiliser des "fonctions de fenêtre" pour ignorer les lignes et limiter les jeux de résultats.
Et dans SQL: 2008, une approche légèrement plus simple avait été ajoutée, utilisant
OFFSET skip ROWS FETCH FIRST n ROWS ONLY
Personnellement, je ne pense pas que l'ajout de SQL: 2008 était vraiment nécessaire, donc si j'étais ISO, je l'aurais gardé hors d'un standard déjà assez grand.
la source
Lorsque nous travaillions dans MSSQL 2000, nous faisions ce que nous appelions le "triple-flip":
ÉDITÉ
Ce n'était pas élégant et ce n'était pas rapide, mais cela a fonctionné.
la source
IF / ELSE IF
blocs sous leOuterPageSize
calcul - aux pages 1 et 2, ils ramèneront laOuterPageSize
valeur à 10. À la page 3 (lignes 21-25), le calcul renverra correctement 5, et sur toutes les pages 4 et supérieures, le résultat négatif du calcul sera remplacé par 0 (bien qu'il serait probablement plus rapide de renvoyer une ligne de données vide immédiatement à ce point).Sélectionnez le nième enregistrement du haut
sélectionner le nième enregistrement du bas
la source
Oracle:
la source
where ROWNUM = x
ne fonctionnera que pour x = 1 dans Oracle DB. iewhere ROWNUM = 2
ne retournera aucune ligne.Dans Oracle 12c, vous pouvez utiliser
OFFSET..FETCH..ROWS
option avecORDER BY
Par exemple, pour obtenir le 3e enregistrement du haut:
la source
Voici une solution rapide de votre confusion.
Ici, vous pouvez obtenir la dernière ligne en remplissant N = 0, l'avant-dernière en N = 1, le quatrième en dernier en remplissant N = 3 et ainsi de suite.
C'est une question très courante au cours de l'entretien et c'est très simple.
En outre, si vous voulez un montant, un ID ou un ordre de tri numérique, vous pouvez utiliser la fonction CAST dans MySQL.
Ici En remplissant N = 4, vous pourrez obtenir le cinquième dernier enregistrement du montant le plus élevé de la table CART. Vous pouvez adapter votre nom de champ et de table et proposer une solution.
la source
AJOUTER:
Cela limitera les résultats à un seul résultat à partir du résultat n.
la source
Par exemple, si vous souhaitez sélectionner chaque 10e ligne dans MSSQL, vous pouvez utiliser;
Prenez simplement le MOD et changez le numéro 10 ici n'importe quel nombre que vous voulez.
la source
Pour SQL Server, une façon générique de procéder par numéro de ligne est la suivante:
Par exemple:
Cela renverra les informations de la 20e ligne. Assurez-vous de mettre le nombre de lignes 0 par la suite.
la source
LIMIT n, 1 ne fonctionne pas dans MS SQL Server. Je pense que c'est à peu près la seule base de données majeure qui ne prend pas en charge cette syntaxe. Pour être honnête, il ne fait pas partie du standard SQL, bien qu'il soit si largement pris en charge qu'il devrait l'être. Dans tout sauf SQL Server LIMIT fonctionne très bien. Pour SQL Server, je n'ai pas pu trouver de solution élégante.
la source
Voici une version générique d'un sproc que j'ai récemment écrit pour Oracle qui permet la pagination / tri dynamique - HTH
la source
Mais vraiment, tout cela n'est-il pas vraiment juste des astuces de salon pour une bonne conception de base de données? Les quelques fois où j'ai eu besoin de fonctionnalités comme celle-ci, c'était pour une simple requête unique pour faire un rapport rapide. Pour tout travail réel, l'utilisation de ces astuces est source de problèmes. Si la sélection d'une ligne particulière est nécessaire, il suffit d'avoir une colonne avec une valeur séquentielle et d'en finir.
la source
Pour SQL Server, ce qui suit renverra la première ligne de la table donnant.
Vous pouvez parcourir les valeurs avec quelque chose comme ceci:
la source
Dans Sybase SQL Anywhere:
N'oubliez pas la COMMANDE PAR ou cela n'a aucun sens.
la source
T-SQL - Sélection d'un numéro d'enregistrement dans une table
Par exemple, pour sélectionner le 5 e enregistrement d'une table Employé, votre requête doit être
la source
la source
J'ai écrit cette requête pour trouver la Nème ligne. Un exemple avec cette requête serait
la source
incroyable que vous puissiez trouver un moteur SQL exécutant celui-ci ...
la source
Rien d'extraordinaire, pas de fonctions spéciales, si vous utilisez Caché comme je le fais ...
Étant donné que vous avez une colonne ID ou une colonne d'horodatage, vous pouvez faire confiance.
la source
C'est ainsi que je le ferais dans DB2 SQL, je crois que le RRN (numéro d'enregistrement relatif) est stocké dans la table par l'O / S;
la source
Sélectionnez d'abord les 100 premières lignes en triant par ordre croissant, puis sélectionnez la dernière ligne en triant par ordre décroissant et limitez à 1. Cependant, il s'agit d'une instruction très coûteuse car elle accède aux données deux fois.
la source
Il me semble que, pour être efficace, vous devez 1) générer un nombre aléatoire entre 0 et un de moins que le nombre d'enregistrements de la base de données, et 2) pouvoir sélectionner la ligne à cette position. Malheureusement, différentes bases de données ont différents générateurs de nombres aléatoires et différentes façons de sélectionner une ligne à une position dans un jeu de résultats - vous spécifiez généralement le nombre de lignes à ignorer et le nombre de lignes que vous souhaitez, mais cela se fait différemment pour différentes bases de données. Voici quelque chose qui fonctionne pour moi dans SQLite:
Cela dépend de pouvoir utiliser une sous-requête dans la clause limit (qui dans SQLite est LIMIT <recs to skip>, <recs to take>) La sélection du nombre d'enregistrements dans une table devrait être particulièrement efficace, faisant partie de la base de données. métadonnées, mais cela dépend de la mise en œuvre de la base de données. De plus, je ne sais pas si la requête va réellement générer le jeu de résultats avant de récupérer le Nième enregistrement, mais j'espère que ce n'est pas nécessaire. Notez que je ne spécifie pas une clause "order by". Il pourrait être préférable de "classer par" quelque chose comme la clé primaire, qui aura un index - obtenir le Nième enregistrement à partir d'un index pourrait être plus rapide si la base de données ne peut pas obtenir le Nième enregistrement de la base de données elle-même sans construire l'ensemble de résultats .
la source
La réponse la plus appropriée que j'ai vue sur cet article pour le serveur SQL
la source