IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

Retrouver la 100ème valeur. Optimisation


Sujet :

SQL Oracle

  1. #1
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 053
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 053
    Points : 9 392
    Points
    9 392
    Par défaut Retrouver la 100ème valeur. Optimisation
    J'ai une table avec une seule colonne COL01 utile pour ce besoin.
    Je veux la 100ème valeur de cette colonne COL01.

    J'ai cette requête, elle convient parfaitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select COL01 from 
    ( select COL01 , rank() over ( order by COL01) as rk  from MaTable )
    where rk = 100
    J'imagine qu'il y a une fonction analytique qui peut faire ça sans requête imbriquée mais je ne la trouve pas.
    Ca c'est mon besoin d'aujourd'hui.

    Mais j'imagine qu'il y a aussi une syntaxe pour réécrire la requête ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select   COL01, COL02, COL03 from 
    ( select  COL01, COL02 ,  COL03 rank() over ( partition by COL01  order by COL02) as rk  from MaTable )
    where rk = 100
    Autrement dit, dans chaque groupe identifié par COL01, récupérer la 100 ème plus petite valeur sur la colonne COL02, et récupérer la description COL03 correspondant à cette 100ème valeur.

    Si au lieu de la 100ème ligne, je veux la 1ère ligne, je sais faire , avec MIN () KEEP (DENSE_RANK ...)
    Mais pour une ligne arbitraire, autre que la 1ère ?
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  2. #2
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    Bonjour,

    Quelle est ta version de base? A partir de la version 11.2 tu as la fonction NTH_VALUE:

    https://docs.oracle.com/cd/E11882_01...htm#SQLRF30031

  3. #3
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    En 12c tu as le OFFSET : https://oracle-base.com/articles/12c...-queries-12cr1

    Exemple pour avoir la 10ème ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    WITH t AS (SELECT LEVEL num FROM dual connect BY LEVEL < 100)
       SELECT num
       FROM t
       ORDER BY num
       OFFSET 9 ROWS FETCH FIRST 1 ROW ONLY
    10

    La 10ème ligne en tri desc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
       WITH t AS (SELECT LEVEL num FROM dual connect BY LEVEL < 100)
       SELECT num
       FROM t
       ORDER BY num desc
     OFFSET 9 ROWS FETCH FIRST 1 ROW ONLY
    90


    Pour ton second cas, je ne pense pas qu'une seule requête non imbriquée le fasse
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 768
    Points : 52 577
    Points
    52 577
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par McM Voir le message
    En 12c tu as le OFFSET : https://oracle-base.com/articles/12c...-queries-12cr1

    Exemple pour avoir la 10ème ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    WITH t AS (SELECT LEVEL num FROM dual connect BY LEVEL < 100)
       SELECT num
       FROM t
       ORDER BY num
       OFFSET 9 ROWS FETCH FIRST 1 ROW ONLY
    10
    ATTENTION : ceci peut être faux.... 100e valeur ne veut pas dire 100e ligne... À cause des ex æquo ! Une requête avec un RANK est donc nécessaire pour ce faire...

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    ATTENTION : ceci peut être faux.... 100e valeur ne veut pas dire 100e ligne... À cause des ex æquo !
    Dans ce cas en effet l'utilisation de RANK() pour faire rnk = 100 peut ne rien ramener même s'il y a plus de 100 lignes. Il faut alors utiliser DENSE_RANK(), mais on peut ramener plusieurs lignes. Le mieux c'est ROW_NUMER() dans ce cas, d'ailleurs sous le capot la ROW LIMITING CLAUSE d'Oracle utilise ROW_NUMBER().

  6. #6
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 053
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 053
    Points : 9 392
    Points
    9 392
    Par défaut
    Je suis en version 12C.

    J'avais regardé nth_value() avant de poser la question, et a priori, ça ne convient pas. Mais je vais fouiller plus, parce que je ne comprends pas à 100% ce que fait cette fonction.

    Offset convient parfaitement. La gestion des ex-aequo me convient. Si mes valeurs sont 1,2,2,3,3,3,4,4 4, 5,5,5 etc. , je considère que la 10ème valeur de cette liste est 5. Et de toutes façons, dans ma clause de tri, je fais en sorte de ne pas avoir d'ex-aequo.

    Merci.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  7. #7
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    Bonjour,

    nth_value ne conviendra pas en effet puisque tu veux une seule ligne. Puisque tu es en 12c tu peux utiliser une requête match_recognize pour ton second point:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select * from matable
     match_recognize(partition by col01
                     order by col02
                     measures match_number() as mn,
                              col02 as col02,
                              col03 as col03
                     pattern (ligne{1}) 
                     define ligne as 1=1          
                    )
    where mn = 100;

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Testé différentes versions avec match_recognize (notamment pattern A{1} et A{100}) sur une table de > 6M objects :
    nécessite plus ou moins 60% du temps de la version avec rank() et pas de différences significatives entre les différents pattern.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Retrouver facilement une valeur dans une table
    Par Papy214 dans le forum Power BI
    Réponses: 0
    Dernier message: 24/11/2017, 13h49
  2. [vb.net][datatable] retrouver extraire des valeur unique
    Par arnolem dans le forum Windows Forms
    Réponses: 4
    Dernier message: 13/01/2006, 10h33
  3. Réponses: 17
    Dernier message: 03/10/2005, 11h16
  4. Encore une question, pour retrouver 2 valeur d'une table
    Par danje dans le forum Langage SQL
    Réponses: 5
    Dernier message: 15/09/2005, 00h11
  5. débogage D6 et valeurs "optimisées" vraiment casse
    Par delphidebutant dans le forum EDI
    Réponses: 3
    Dernier message: 11/07/2005, 16h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo