mysql - requete - sql limit
Comment sélectionner la nième ligne dans une table de base de données SQL? (19)
SERVEUR SQL
Sélectionnez le nième disque en haut
SELECT * FROM (
SELECT
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID) AS ROW
FROM TABLE
) AS TMP
WHERE ROW = n
sélectionner n 'ème enregistrement du bas
SELECT * FROM (
SELECT
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID DESC) AS ROW
FROM TABLE
) AS TMP
WHERE ROW = n
Je suis intéressé par l'apprentissage (idéalement) des méthodes agnostiques de base de données de la sélection de la nième rangée à partir d'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 suis en train de faire quelque chose comme ce qui suit dans SQL Server 2005, mais je serais intéressé de voir les approches plus agnostiques des autres:
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: Weblog 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?
1 petit changement: n-1 au lieu de n.
select *
from thetable
limit n-1, 1
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;
SELECT * FROM (
SELECT RRN(FOO) AS RRN, FOO.*
FROM FOO
ORDER BY RRN(FOO)) BAR
WHERE BAR.RRN = recordnumber
Contrairement à ce que prétendent certaines réponses, la norme SQL n'est pas muette sur ce sujet.
Depuis SQL: 2003, vous pouvez utiliser des "fonctions de fenêtre" pour ignorer les lignes et limiter les ensembles de résultats.
Et dans SQL: 2008, une approche légèrement plus simple a été ajoutée, en 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 écarté d'une norme déjà assez grande.
Dans Sybase SQL Anywhere:
SELECT TOP 1 START AT n * from table ORDER BY whatever
Ne pas oublier la commande ou c'est sans signification.
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 base de données, et 2) être capable de 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 manières de sélectionner une ligne à un emplacement dans un ensemble de résultats. En général, vous spécifiez le nombre de lignes à ignorer et le nombre de lignes souhaitées. Voici quelque chose qui fonctionne pour moi dans SQLite:
select *
from Table
limit abs(random()) % (select count(*) from Words), 1;
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éta-données, mais cela dépend de la mise en œuvre de la base de données. En outre, je ne sais pas si la requête va réellement construire 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 peut être préférable de "trier" quelque chose comme la clé primaire, qui aura un index - obtenir le Nième enregistrement 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 sans construire le jeu de résultats .
Je ne suis pas sûr de tout le reste, mais je sais que SQLite et MySQL n'ont aucun ordre de rangée "par défaut". Dans ces deux dialectes, au moins, l'extrait suivant récupère la 15ème entrée de the_table, en la triant par date / heure d'ajout:
SELECT * FROM the_table ORDER BY added DESC LIMIT 1,15
(bien sûr, vous devez avoir un champ DATETIME ajouté, et le définir à la date / heure que l'entrée a été ajoutée ...)
Je soupçonne que c'est très inefficace, mais c'est une approche assez simple, qui a travaillé sur un petit jeu de données sur lequel j'ai essayé.
select top 1 field
from table
where field in (select top 5 field from table order by field asc)
order by field desc
Ceci obtiendrait le 5ème article, changez le deuxième nombre supérieur pour obtenir un nième article différent
Serveur SQL seulement (je pense) mais devrait fonctionner sur les anciennes versions qui ne supportent pas ROW_NUMBER ().
La syntaxe LIMIT
/ OFFSET
dans PostgreSQL est:
SELECT
*
FROM
mytable
ORDER BY
somefield
LIMIT 1 OFFSET 20;
Cet exemple sélectionne la 21ème ligne. OFFSET 20
indique à Postgres d'ignorer les 20 premiers enregistrements. Si vous ne spécifiez pas de clause ORDER BY
, il n'y a aucune garantie quant à l'enregistrement que vous obtiendrez, ce qui est rarement utile.
Apparemment, la norme SQL est silencieuse sur le problème de la limite en dehors des fonctions de fenêtrage fou, ce qui explique pourquoi tout le monde l'implémente différemment.
Mais vraiment, tout cela n'est-il pas vraiment juste des trucs de salon pour une bonne conception de base de données en premier lieu? Les quelques fois où j'ai eu besoin d'une fonctionnalité comme celle-ci, c'était pour une simple requête unique pour faire un rapport rapide. Pour tout vrai travail, l'utilisation de trucs comme ceux-ci est une source d'ennuis. 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 avec elle.
Par exemple, si vous voulez sélectionner chaque 10ème ligne dans MSSQL, vous pouvez utiliser;
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ColumnName1 ASC) AS rownumber, ColumnName1, ColumnName2
FROM TableName
) AS foo
WHERE rownumber % 10 = 0
Il suffit de prendre le MOD et de changer le numéro 10 ici n'importe quel nombre que vous voulez.
Pour SQL Server, une manière générique de passer par numéro de ligne est la suivante: SET ROWCOUNT @row - @ row = le numéro de ligne sur lequel vous souhaitez travailler.
Par exemple:
set rowcount 20 --définit la ligne à la 20ème rangée
choisir la viande, le fromage de dbo.sandwich - sélectionner les colonnes de la table au 20ème rang
set rowcount 0 --définit rowcount sur toutes les lignes
Cela retournera les informations de la 20ème rangée. Assurez-vous de mettre dans le rowcount 0 après.
Je connais Noobish, mais je suis un SQL Noob et je l'ai utilisé alors que puis-je dire?
Rien d'extraordinaire, pas de fonctions spéciales, au cas où vous utilisez Caché comme je le fais ...
SELECT TOP 1 * FROM (
SELECT TOP n * FROM <table>
ORDER BY ID Desc
)
ORDER BY ID ASC
Étant donné que vous avez une colonne ID ou une colonne datastamp vous pouvez faire confiance.
SQL 2005 et supérieur a 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:
SELECT
*
FROM
(
SELECT
ROW_NUMBER () OVER (ORDER BY MyColumnToOrderBy) AS RowNum,
*
FROM
Table_1
) sub
WHERE
RowNum = 23
Vérifiez-le sur SQL Server:
Select top 10 * From emp
EXCEPT
Select top 9 * From emp
Cela vous donnera 10ème RANG de table emp!
Voici une solution rapide de votre confusion.
SELECT * FROM table ORDER BY `id` DESC LIMIT N, 1
Ici, vous pouvez obtenir la dernière ligne en remplissant N = 0, la deuxième en dernier par N = 1, la quatrième en remplissant N = 3 et ainsi de suite.
C'est une question très commune au cours de l'interview et c'est très simple.
Plus loin Si vous voulez un montant, un identifiant ou un ordre de tri numérique, vous pouvez opter pour la fonction CAST dans MySQL.
SELECT DISTINCT (`amount`) FROM cart ORDER BY CAST( `amount` AS SIGNED ) DESC LIMIT 4 , 1
En remplissant N = 4, vous pourrez obtenir le cinquième enregistrement du montant le plus élevé de la table CART. Vous pouvez adapter votre nom de champ et de table et trouver la solution.
incroyable que vous pouvez trouver un moteur SQL exécutant celui-ci ...
WITH sentence AS
(SELECT
stuff,
row = ROW_NUMBER() OVER (ORDER BY Id)
FROM
SentenceType
)
SELECT
sen.stuff
FROM sentence sen
WHERE sen.row = (ABS(CHECKSUM(NEWID())) % 100) + 1
SELECT
top 1 *
FROM
table_name
WHERE
column_name IN (
SELECT
top N column_name
FROM
TABLE
ORDER BY
column_name
)
ORDER BY
column_name DESC
J'ai écrit cette requête pour trouver Nth row. Exemple avec cette requête serait
SELECT
top 1 *
FROM
Employee
WHERE
emp_id IN (
SELECT
top 7 emp_id
FROM
Employee
ORDER BY
emp_id
)
ORDER BY
emp_id DESC
select * from
(select * from ordered order by order_id limit 100) x order by
x.order_id desc limit 1;
Commencez par sélectionner les 100 premières lignes en les classant par ordre croissant, puis sélectionnez la dernière ligne en les ordonnant en descendant et en les limitant à 1. Toutefois, cette instruction est très coûteuse car elle accède aux données deux fois.