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 :

Conception de requête via sous-requête et rownum


Sujet :

SQL Oracle

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Conception de requête via sous-requête et rownum
    Bonjour à tous,

    Je n'ai pas trouvé de solution à mon problème dans les archives, alors je poste là.

    J'ai une requête SQL qui me renvoie ce genre de résultat

    IDENTIFIANT SOUS_IDENTIFIANT
    001 1001
    001 30125
    002 30124
    002 30123
    002 30146
    003 35874
    003 01245
    004 01254

    Ma question est donc, comment n'afficher pour chaque identifiant qu'a partir du 2eme sous identifiant.

    Mon but étant de rogner le premier sous identifiant pour chaque identifiant. J'ai essayer avec un rownum, avec des group by, tout et tout. Sans succès. Je vous passe par contre, la requête d'une complexité affligeante ...

    select IDENTIFIANT, SOUS_IDENTIFIANT
    from table
    order by 1,2;

    Merci d'avance a ceux qui voudront bien m'aider.

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 555
    Points
    38 555
    Billets dans le blog
    9
    Par défaut
    Si votre SGBD le permet (quel est il), utilisez la fonction de fenetrage RANK
    Edit : vous pouvez aussi utiliser EXCEPT

  3. #3
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 555
    Points
    38 555
    Billets dans le blog
    9
    Par défaut
    Exemple de solution avec RANK (inutilisable si vous utilisez MySQL ou Access)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    With mycte as(
    select distinct RANK()                                              
               over (partition by col1 order by Col2) as rang
             , col1                                                    
             , col2                                                    
             , ...                                                    
             , coln
    from ma_table
    where ...)
    Select * from mycte where rang > 1
    Si votre SGBD n'accepte pas les fonctions de fenêtrage, voici une solution avec except
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Select * from (
    select col1
         , col2
         , ...
         , coln
    from ma_table
    EXCEPT
    select col1
         , col2
         , ...
         , coln
    from ma_table as main
    where not exists
         (select 1
          from ma_table as subq
          where subq.col1 = main.col1
            and subq.col2 < main.col2)
    ) as temp
    order by col1, col2
    Edit : je viens de corriger la requete 2 dans laquelle il y avait une erreur, à tester quand même car rédigé sans test, des fautes de frappe sont possibles

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    La première fonctionne parfaitement au bout de 12800 secondes d’exécution...Mais malheureusement,c'est bien trop long, J’essaye de voir donc pour l'optimiser.

    Mais sinon c'est fonctionnel. J’essaye de voir si c'est plus rapide avec la deuxième du coup.

    Merci a vous deux !!!

    Edit : Je suis sous oracle.

  6. #6
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Une proposition basée sur la deuxième solution d'escartefigue (usage d'EXCEPT):

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select IDENTIFIANT, SOUS_IDENTIFIANT
    from ma_table
    EXCEPT
    select IDENTIFIANT, MIN(SOUS_IDENTIFIANT)
    from ma_table 
    group by IDENTIFIANT

    Cela fonctionne car, si j'ai bien compris, on est dans le cas où les identifiants et sous-identifiants sont triés. Du coup, pour avoir le premier, on peut se servir de MIN
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  7. #7
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 555
    Points
    38 555
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par lordjs Voir le message
    La première fonctionne parfaitement au bout de 12800 secondes d’exécution...Mais malheureusement,c'est bien trop long, J’essaye de voir donc pour l'optimiser.
    Mais sinon c'est fonctionnel. J’essaye de voir si c'est plus rapide avec la deuxième du coup.
    Merci a vous deux !!!
    Edit : Je suis sous oracle.
    C'est beaucoup beaucoup trop long ! et étonnamment trop long, quel volume dans la table ?
    Le distinct n'est peut être pas requis dans votre cas

    Citation Envoyé par dorinf Voir le message
    Bonjour,
    Une proposition basée sur la deuxième solution d'escartefigue (usage d'EXCEPT):
    C'est ce qui est amusant avec SQL : d'avoir le plus souvent plusieurs solutions avec des variantes pour un même besoin
    Il reste ensuite à choisir la plus efficace en fonction du contexte

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    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 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    Plus simple...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE MaTable (IDENTIFIANT CHAR(3),  SOUS_IDENTIFIANT CHAR(5))
     
    INSERT INTO MaTable VALUES
    ('001', '1001'),
    ('001', '30125'),
    ('002', '30124'),
    ('002', '30123'),
    ('002', '30146'),
    ('003', '35874'),
    ('003', '01245'),
    ('004', '01254');
    Solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT T2.IDENTIFIANT, MIN(T2.SOUS_IDENTIFIANT) AS SOUS_IDENTIFIANT2
    FROM   MaTable AS T1
           JOIN MaTable  AS T2
    	        ON T1.IDENTIFIANT = T2.IDENTIFIANT AND T1.SOUS_IDENTIFIANT > T2.SOUS_IDENTIFIANT
    GROUP  BY  T2.IDENTIFIANT;
    Résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    IDENTIFIANT SOUS_IDENTIFIANT2
    ----------- -----------------
    001         1001 
    002         30123
    003         01245
    Si cela vous pose des problèmes de performances, créez l'index suivant :
    CREATE INDEX X ON MaTable (IDENTIFIANT, SOUS_IDENTIFIANT)

    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/ * * * * *

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Alors concrètement, le rank marche très bien maintenant que j'ai optimiser ma requête et que les latences de bdd sont terminés.

    Concernant l'except, ce n'est pas disponible sur Oracle, mais la fonction MINUS fait du coup parfaitement l'affaire.

    Du coup, niveau temps d’exécution, je viens de comparer les deux et le MINUS offre des temps supérieurs a l'autre.

    Je garde donc le rank.

    C'est bon pour moi, je clôture ce topic.

    Je vous remercie bien de votre aide.

    C'est ce qui est amusant avec SQL : d'avoir le plus souvent plusieurs solutions avec des variantes pour un même besoin
    Il reste ensuite à choisir la plus efficace en fonction du contexte
    =>>>>> Tout a fait !

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

Discussions similaires

  1. Sous requête de sous requête qui ne marche pas
    Par mactwist69 dans le forum Développement
    Réponses: 2
    Dernier message: 27/10/2016, 17h24
  2. intégré une sous requête dans une requête
    Par Smix007 dans le forum SQL
    Réponses: 13
    Dernier message: 25/06/2007, 11h45
  3. inclure une sous requête dans une requête
    Par garsflo dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 08/05/2007, 19h12
  4. Requête et sous requête avec SELECT et UPDATE
    Par Véronique75ca dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 29/06/2006, 21h25
  5. Requêtes et sous requêtes
    Par lau2nyce dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/03/2004, 15h14

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