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 :

Besoin d'aide pour des requêtes


Sujet :

SQL Oracle

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 39
    Points : 19
    Points
    19
    Par défaut Besoin d'aide pour des requêtes
    Bonjour,

    Désolé pour le titre du sujet, je n'ai rien trouvé de mieux

    Il y a deux requêtes que je n'arrive pas à faire malgré plusieurs tentatives et en essayant de bricoler par-ci par-là

    Je vous donne d'abord mes tables pour que ce soit plus clair. Je ne mets pas tous les attributs pour une question de clareté.
    (en italique la clé primaire)
    Pays (CodePays, NomPays)
    Coureurs (NumeroCoureur, NomCoureur, CodePays)
    Etapes (NumeroEtape, DateEtape)
    Temps (NumeroCoureur, NumeroEtape, TempsRealise)

    Requête 1 : Combien d'étapes ont été remportées par un espagnol ?
    Requête 2 : Quels sont les noms des coureurs qui ont participé à toutes les étapes ?

    Ce que j'ai essayé de faire

    Code Requete 1 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT COUNT(*) FROM PAYS, COUREURS, TEMPS
    WHERE PAYS.NomPays = 'Espagne'
    AND PAYS.CodePays = COUREURS.CodePays
    AND TEMPS.TempsRealise IN (SELECT MIN (TempsRealise) FROM TEMPS GROUP BY NumeroEtape)
    AND COUREURS.NumeroCoureur = TEMPS.NumeroCoureur
    GROUP BY NumeroEtape;

    Code Requete 2 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT * FROM TEMPS
    WHERE (SELECT COUNT(*) FROM ETAPES) IN
    (SELECT COUNT(*) FROM TEMPS, COUREURS
    WHERE TEMPS.NumeroCoureur = COUREURS.NumeroCoureur
    GROUP BY COUREURS.NumeroCoureur);

    Bien sûr ça ne marche pas, je comprends pourquoi, mais je n'arrive pas à trouver la solution

    Rappel du dernier message :
    Par contre j'ai une autre requête :
    Lister les coureurs satisfaisant au moins une des trois condition :
    - avoir distancé Armstrong d'au moins 10 min
    - avoir un espagnol et un suisse dans son equipe
    - ne jamais avoir été battu par un membre de son équipe à une étape

    Pour les deux premiers points pas de soucis, par contre le troisième je galère un peu plus

    Merci d'avance

    Cordialement,
    pikmin

  2. #2
    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
    Dans ta première requête, c'est ta recherche du meilleur temps qui n'est pas bon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND TEMPS.TempsRealise IN (SELECT MIN (TempsRealise) FROM TEMPS GROUP BY NumeroEtape)
    Inspire toi de ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT a.* 
    FROM TEMPS a
    WHERE a.tps = (SELECT min(tps) FROM TEMPS b WHERE b.course = a.course)
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  3. #3
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    pour la seconde requête j'ai trouvé en m'inspirant de ce que tu m'as proposé pour la première (oui je sais c'est pas forcément logique)

    Code Requête 2 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT NomCoureur FROM COUREURS C1
    WHERE (SELECT COUNT(*) FROM ETAPES) IN
    (SELECT COUNT(*) FROM TEMPS, COUREURS C2
    WHERE TEMPS.NumeroCoureur = C2.NumeroCoureur
    AND C1.NumeroCoureur = C2.NumeroCoureur
    GROUP BY C2.NumeroCoureur);

    Pour la première j'ai essayé de faire pareil mais je n'y suis pas arrivé Du coup j'ai fait autre chose. Ce n'est pas totalement juste, mais ça fera l'affaire

    Code Requête 1 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT COUNT (*) FROM (
    SELECT MIN (TempsRealise) FROM TEMPS GROUP BY NumeroEtape
    INTERSECT
    SELECT TempsRealise FROM PAYS, COUREURS, TEMPS
    WHERE PAYS.NomPays = 'Espagne'
    AND PAYS.CodePays = COUREURS.CodePays
    AND COUREURS.NumeroCoureur = TEMPS.NumeroCoureur);

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 383
    Points
    18 383
    Par défaut
    Vous n'avez pas besoin de tant d'imbrications dans vos requêtes.
    Par exemple, vous pouvez écrire la seconde de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      select c.numerocoureur, c.nomcoureur
        from coureurs c
             inner join temps t
               on t.numerocoureur = c.numerocoureur
    group by c.numerocoureur, c.nomcoureur
      having count(*) = (select count(*) from etapes)

  5. #5
    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
    Ta seconde requête est fausse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MIN (TempsRealise) FROM TEMPS GROUP BY NumeroEtape
    Va te renvoyer tous les temps minimum de chaque étape, exemple
    => 10, 15, 10


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT TempsRealise FROM PAYS, COUREURS, TEMPS
    WHERE PAYS.NomPays = 'Espagne'
    AND PAYS.CodePays = COUREURS.CodePays
    AND COUREURS.NumeroCoureur = TEMPS.NumeroCoureur);
    Va te renvoyer les temps de tous les coureurs Espagnols sur toutes les courses
    => donc tu peux avoir pour la course 1 un temps minimum de 10, et un coureur espagnol qui a fait 15.

    L'intersect va être ok, alors que c'est pas bon.
    La technique est bien trouvée, mais il faut que tu rajoutes le n° étape dans ton intersect

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT COUNT (*) FROM (
    SELECT NumeroEtape, MIN (TempsRealise) FROM TEMPS GROUP BY NumeroEtape
    INTERSECT
    SELECT NumeroEtape, TempsRealise FROM PAYS, COUREURS, TEMPS
    WHERE PAYS.NomPays = 'Espagne'
    AND PAYS.CodePays = COUREURS.CodePays
    AND COUREURS.NumeroCoureur = TEMPS.NumeroCoureur);
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 383
    Points
    18 383
    Par défaut
    J'aurai écrit la première requête de cette façon-là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select count(*)
      from Coureurs c
           inner join Pays p
             on p.CodePays = c.CodePays
           inner join
            (  select min(NumeroCoureur) keep(dense_rank first order by TempsRealise asc) as NumeroCoureur
                 from Temps
             group by NumeroEtape) sr
           on sr.NumeroCoureur = c.NumeroCoureur
     where p.Nompays = 'Espagne'

  7. #7
    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
    Ouais, surement, mais je doute que le prof comprenne le DENSE_RANK
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 383
    Points
    18 383
    Par défaut
    Pas faux, voici la version non-Oracle compliant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    select count(*)
      from Coureurs c
           inner join Pays p
             on p.CodePays = c.CodePays
           inner join Temps t
             on t.NumeroCoureur = c.NumeroCoureur
           inner join
            (  select NumeroEtape, min(TempsRealise) as TempsRealiseMin
                 from Temps
             group by NumeroEtape) sr
           on sr.NumeroEtape = t.NumeroEtape
          and sr.TempsRealiseMin = t.TempsRealise
     where p.Nompays = 'Espagne'

  9. #9
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par McM Voir le message
    Ta seconde requête est fausse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MIN (TempsRealise) FROM TEMPS GROUP BY NumeroEtape
    Va te renvoyer tous les temps minimum de chaque étape, exemple
    => 10, 15, 10


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT TempsRealise FROM PAYS, COUREURS, TEMPS
    WHERE PAYS.NomPays = 'Espagne'
    AND PAYS.CodePays = COUREURS.CodePays
    AND COUREURS.NumeroCoureur = TEMPS.NumeroCoureur);
    Va te renvoyer les temps de tous les coureurs Espagnols sur toutes les courses
    => donc tu peux avoir pour la course 1 un temps minimum de 10, et un coureur espagnol qui a fait 15.

    L'intersect va être ok, alors que c'est pas bon.
    La technique est bien trouvée, mais il faut que tu rajoutes le n° étape dans ton intersect
    c'est pour ça que j'ai dis "Ce n'est pas totalement juste, mais ça fera l'affaire"
    En tout cas merci, maintenant c'est impec

    Par contre j'ai une autre requête :
    Lister les coureurs satisfaisant au moins une des trois condition :
    - avoir distancé Armstrong d'au moins 10 min
    - avoir un espagnol et un suisse dans son equipe
    - ne jamais avoir été battu par un membre de son équipe à une étape

    Pour les deux premiers points pas de soucis, par contre le troisième je galère un peu plus

  10. #10
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 39
    Points : 19
    Points
    19
    Par défaut
    J'ai essayé d'autres trucs, mais toujours infructueux.
    Si on prend les temps minimaux de chaque équipe par étape, on obtient ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    MIN(TEMPSREALISE) CODEE NUMEROETAPE
    ----------------- ----- -----------
                   90 Code2           1
                  100 Code2           2
                  140 Code2           3
                   89 Code3           1
                   70 Code3           2
                  140 Code3           3
                  100 Code1           1
                   80 Code1           2
                  150 Code1           3
    Ensuite je souhaite additionner les temps pour une même équipe (330 pour Code2, 299 pour Code3 et 330 pour Code1) et voir quels coureurs à ce temps. Si un coureur à ce temps, alors c'est qu'il n'a jamais été battu par un coéquipier sur une étape.
    Le problème est que je n'arrive pas à faire l'addition pour chaque équipe

    Merci d'avance

  11. #11
    Membre averti Avatar de mongilotti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Février 2003
    Messages : 314
    Points : 303
    Points
    303
    Par défaut
    Cette requete servira dans le tour de france cette année!!!

Discussions similaires

  1. Besoin d'aide pour des requêtes SQL
    Par Quentelp dans le forum Langage SQL
    Réponses: 4
    Dernier message: 04/05/2015, 16h12
  2. besoin d'aide pour des algos
    Par mathieu77 dans le forum Algorithmes et structures de données
    Réponses: 23
    Dernier message: 08/11/2005, 18h33
  3. Besoin d'aide pour optimiser requête SQL
    Par Keuf95 dans le forum Langage SQL
    Réponses: 10
    Dernier message: 06/09/2005, 16h02
  4. Besoin d'aide pour une Requête SQL ...
    Par Kokito dans le forum Requêtes
    Réponses: 2
    Dernier message: 07/07/2004, 11h56
  5. besoin d'aide pour une requête
    Par Damien69 dans le forum Langage SQL
    Réponses: 11
    Dernier message: 31/03/2004, 15h38

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