Pouvez-vous nous dire l'ordre selon lequel vous voulez 'top 1'?
Andrew Wolfe
1
Tout d'abord, vous ne devriez jamais compter sur le moteur DB pour le faire. Si vous voulez savoir des choses comme ça, mettez un séquenceur. Lorsque vous faites cela, il est garanti qu'ils seront numérotés dans l'ordre où ils ont été insérés.
C'est bien si vous ne voulez qu'une seule ligne et que vous ne vous en souciez pas. Si vous voulez des lignes spécifiques, comme l'enregistrement le plus récent, vous devez faire le tri dans une sous-sélection, comme la réponse de Vash. Oracle attribue des rownums avant le tri.
Scott Bailey
4
@Scott yup. c'est exact. Et Patrick, bon point, je pense que la syntaxe est incorrecte à ce sujet. Cela devrait vraiment être un garder (dense_rank () dernier ...)
mcpeterson
2
La différence entre le premier et le deuxième exemple est que le premier sélectionne une ligne (n'importe quelle ligne, sans ordre). Le deuxième exemple obtient la valeur de la première ligne, sans faire de requête interne de commande (selon les exemples ci-dessous).
JulesLt
3
La syntaxe n'est pas correcte dans: sélectionnez max (fname) sur (classement () par some_factor) de MyTbl
Stéphane Gerber
1
@jclozano "pas une fonctionnalité très connue d'Oracle" - Avec respect, je vous prie de différer. Cela est important car «des fonctionnalités peu connues» impliquent généralement de l'obscurité et pourraient donc suggérer que nous devrions éviter de les utiliser. Ce n'est pas obscur et son utilisation ne doit pas être évitée.
Commande intéressante, j'utilise ici 12c et ce OFFSET 0 ROWSn'est apparemment pas nécessaire, vous pouvez utiliser FETCH NEXT 1 ROWS ONLYou même FETCH FIRST ROW ONLY, l'ordre par est important ou ce sera équivalent à simplement utiliser un WHERE rownum = 1. Je l'ai même essayé dans une instruction OUTER APPLY et cela a fonctionné comme la fonction TOP de Ms-SQL.
Rafael Merlin
Vous avez raison @RafaelMerlin. Après votre message, j'ai reconnu que OFFSET 0 ROWS n'est pas nécessaire. Il serait utile lors de la récupération de données entre le X supérieur et le Y supérieur.
Jusqu'ici tout va bien, avec un point manquant important qui est TIES. Reportez - vous ceci pour les cas où des liens se produisent pour la version 12c +et12c -
Barbaros Özhan
10
Vous pouvez utiliser ROW_NUMBER()une ORDER BYclause en sous-requête et utiliser cette colonne en remplacement de TOP N. Cela peut être expliqué étape par étape.
Voir le tableau ci-dessous qui a deux colonnes NAMEet DT_CREATED.
Si vous devez prendre uniquement les deux premières dates indépendamment de NAME, vous pouvez utiliser la requête ci-dessous. La logique a été écrite dans la requête
-- The number of records can be specified in WHERE clauseSELECT RNO,NAME,DT_CREATEDFROM(-- Generates numbers in a column in sequence in the order of dateSELECT ROW_NUMBER()OVER(ORDERBY DT_CREATED)AS RNO,
NAME,DT_CREATEDFROM DEMOTOP)TABWHERE RNO<3;
RÉSULTAT
Dans certaines situations, nous devons sélectionner des TOP Nrésultats respectifs à chacun NAME. Dans ce cas, nous pouvons utiliser PARTITION BYune ORDER BYclause en sous-requête. Reportez-vous à la requête ci-dessous.
-- The number of records can be specified in WHERE clauseSELECT RNO,NAME,DT_CREATEDFROM(--Generates numbers in a column in sequence in the order of date for each NAMESELECT ROW_NUMBER()OVER(PARTITIONBY NAME ORDERBY DT_CREATED)AS RNO,
NAME,DT_CREATEDFROM DEMOTOP)TABWHERE RNO<3;
L'utilisation de ROW_NUMBER () ... est une solution plus correcte que dans la réponse au sujet. Un problème avec cette solution (et avec la variante max (champ) aussi) que vous ne pouvez pas faire des choses comme "sélectionnez ... (sélectionnez ROW_NUMBER () ...) pour la mise à jour ;"
Alexo Po.
Et c'est parfois très important en PL / SQL (désolé, impossible de modifier le commentaire précédent en 5 minutes maximum).
Alexo Po.
Dans ce cas, nous pouvons utiliser CTE comme dans la partie extérieure. Droite? @Alexo Po.
Sarath Avanavu
Je pense que je ne vous comprends pas. La clause for update peut être utilisée lorsque ROWID est "facilement" conservé par Oracle. Ainsi, le regroupement (et le regroupement en raison de l'utilisation de la clause analytique) masque le véritable ROWID et les lignes ne peuvent pas être verrouillées. Et deuxièmement, CTE ( with (select ... ) as clause) ne change rien à ce problème, CTE vise simplement à lire et à prendre en charge les requêtes. Droite? @Sarath Avanavu
Alexo Po.
Remarque sur moi. Le problème avec ROWID se produit en fait spécifiquement en raison de la condition RNO <3 , dans ce cas, la valeur de RNO n'est pas connectée à ROWID, c'est pourquoi Oracle ne peut pas verrouiller les lignes.
Alexo Po.
9
Vous pouvez faire quelque chose comme
SELECT*FROM(SELECT Fname FROM MyTbl ORDERBY Fname )WHERE rownum =1;
Vous pouvez également utiliser les fonctions analytiques RANK et / ou DENSE_RANK , mais ROWNUM est probablement la plus simple.
@carpenteri: Certes, les analyses étaient disponibles dans 8i - je ne me souviens pas des détails, mais les analyses n'étaient pas vraiment accessibles au public avant 9i.
OMG Ponies
Petit commentaire - La réponse de Vash ci-dessous comprend un ORDER BY sur la requête interne qui est critique si vous voulez la valeur TOP de fname, plutôt que 'first' (qui peut être n'importe quoi, probablement la première ligne insérée). Cela pourrait-il valoir la peine d'être modifié?
JulesLt
@JulesLt: La requête fournie par l'OP n'inclut pas de ORDER BY, c'est donc la réponse qui représente et la traduction exacte vers la syntaxe Oracle.
OMG Ponies
Ma mauvaise compréhension de la syntaxe SQL SERVER TOP (présumé à tort qu'elle était similaire à FIRST dans RANK, pas à ROWNUM). A voté.
JulesLt
3
Pour sélectionner la première ligne d'un tableau et pour sélectionner une ligne dans un tableau, deux tâches différentes nécessitent une requête différente. Il existe de nombreuses façons de le faire. Quatre d'entre eux sont:
Première
select max(Fname)from MyTbl;
Seconde
select min(Fname)from MyTbl;
Troisième
select Fname from MyTbl where rownum =1;
Quatrième
select max(Fname)from MyTbl where rowid=(select max(rowid)from MyTbl)
Réponses:
Si vous souhaitez uniquement une première ligne sélectionnée, vous pouvez:
Vous pouvez également utiliser des fonctions analytiques pour commander et prendre le top x:
la source
la source
top X
quelqu'un peut le changer enWHERE ROWNUM <= X
Avec Oracle 12c (juin 2013), vous pouvez l'utiliser comme suit.
la source
OFFSET 0 ROWS
n'est apparemment pas nécessaire, vous pouvez utiliserFETCH NEXT 1 ROWS ONLY
ou mêmeFETCH FIRST ROW ONLY
, l'ordre par est important ou ce sera équivalent à simplement utiliser unWHERE rownum = 1
. Je l'ai même essayé dans une instruction OUTER APPLY et cela a fonctionné comme la fonction TOP de Ms-SQL.TIES
. Reportez - vous ceci pour les cas où des liens se produisent pour la version12c +
et12c -
Vous pouvez utiliser
ROW_NUMBER()
uneORDER BY
clause en sous-requête et utiliser cette colonne en remplacement deTOP N
. Cela peut être expliqué étape par étape.Voir le tableau ci-dessous qui a deux colonnes
NAME
etDT_CREATED
.Si vous devez prendre uniquement les deux premières dates indépendamment de
NAME
, vous pouvez utiliser la requête ci-dessous. La logique a été écrite dans la requêteRÉSULTAT
Dans certaines situations, nous devons sélectionner des
TOP N
résultats respectifs à chacunNAME
. Dans ce cas, nous pouvons utiliserPARTITION BY
uneORDER BY
clause en sous-requête. Reportez-vous à la requête ci-dessous.RÉSULTAT
la source
with (select ... ) as
clause) ne change rien à ce problème, CTE vise simplement à lire et à prendre en charge les requêtes. Droite? @Sarath AvanavuVous pouvez faire quelque chose comme
Vous pouvez également utiliser les fonctions analytiques RANK et / ou DENSE_RANK , mais ROWNUM est probablement la plus simple.
la source
la source
Utilisation:
Si vous utilisez Oracle9i +, vous pouvez envisager d' utiliser des fonctions analytiques comme ROW_NUMBER (), mais elles ne fonctionneront pas aussi bien que ROWNUM .
la source
Pour sélectionner la première ligne d'un tableau et pour sélectionner une ligne dans un tableau, deux tâches différentes nécessitent une requête différente. Il existe de nombreuses façons de le faire. Quatre d'entre eux sont:
Première
Seconde
Troisième
Quatrième
la source
J'ai eu le même problème, et je peux résoudre ce problème avec cette solution:
Vous pouvez commander votre résultat avant d'avoir la première valeur en haut.
Bonne chance
la source