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 :

Requête (casse tête)


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    401
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 401
    Points : 120
    Points
    120
    Par défaut Requête (casse tête)
    Bonjour à tous,

    j'ai besoin de vos lumières pour une requête que je souhaite simplifier.

    Voilà la logic de la chose.

    J'ai une table avec trois colonnes :

    - nom
    - date_debut
    - date_fin

    Si je fais un select distinct de nom sur l'ensemble des tuples je vais retrouver 10 noms différents pour 2 millions de ligne.

    Je souhaite afficher pour chacun de ses noms la date_debut la plus récente.

    La seule soluce que j'ai trouvé dans un premier temps est de faire 10 requetes avec 9 UNION.

    Quelqu'un aurait une requête plus légère à me proposer ?

    Merci d'avance.

  2. #2
    Membre confirmé Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Points : 481
    Points
    481
    Par défaut
    Bonjour,
    un ?

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    401
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 401
    Points : 120
    Points
    120
    Par défaut
    Citation Envoyé par chrifo
    Bonjour,
    un ?
    Le group by va renvoyer la totalité des dates

  4. #4
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select nom, min(date_debut) 
    from TA_TABLE
    group by nom

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    Ca va donner la date_debut la plus vieille pour le logiciel pas la plus récente.
    Et il faut que l'on récupère la date_fin aussi.

    Et mettre select nom, max(date_debut) from table group by nom ne marche pas.
    Car il faut spécifier des fonctions d'aggrégation pour chaque colonne, donc la requête ça serait un truc du genre :
    select nom, max(date_debut), max(date_fin) from table group by nom
    Mais dans ce cas on a plus la date_fin qui correspond à la date_debut mais la plus grosse date_fin pour l'entrée qui porte le nom "nom".

  6. #6
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Merci de fournir, dans vos messages, la version de la base en question.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    Oracle 10 si je ne me trompe pas.

  8. #8
    Membre confirmé Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Points : 481
    Points
    481
    Par défaut
    Citation Envoyé par oxman
    select nom, max(date_debut), max(date_fin) from table group by nom
    Mais dans ce cas on a plus la date_fin qui correspond à la date_debut mais la plus grosse date_fin pour l'entrée qui porte le nom "nom".
    Alors il faut une sous requete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select sreq_table.*, table.date_fin
    from
       table 
       inner join (select nom, max(date_debut) date_debut from table group by nom) sreq_table on table.nom = sreq_table.nom and table.date_debut = sreq_table.date_debut
    ;

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    Merci

  10. #10
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Citation Envoyé par oxman
    Ca va donner la date_debut la plus vieille pour le logiciel pas la plus récente.
    Oups désolé il falait mettre un "max" au lieu du "min"

    Citation Envoyé par oxman
    Et il faut que l'on récupère la date_fin aussi.
    Ah oui mais c'était pas ce que tu avais demandé au départ....

    Citation Envoyé par oxman
    Et mettre select nom, max(date_debut) from table group by nom ne marche pas.
    si...

    Citation Envoyé par oxman
    Car il faut spécifier des fonctions d'aggrégation pour chaque colonne
    ... qui n'est pas dans le "group by" nuance.

    Citation Envoyé par oxman
    , donc la requête ça serait un truc du genre :
    select nom, max(date_debut), max(date_fin) from table group by nom
    Mais dans ce cas on a plus la date_fin qui correspond à la date_debut mais la plus grosse date_fin pour l'entrée qui porte le nom "nom".
    Si tu as besoin de récupérer la date de fin qui correspond au max de la date de début effectivement, tu as raison.

    Outre la solution de chrifo, grace au nouvelles fonctionalités SQL de la 9i, tu dois avoir aussi un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select nom,
     max(date_debut),
     max (date_fin) keep (DENSE_RANK FIRST ORDER BY date_debut desc)
    from ma_table
    group by nom

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    Wow, c'est énorme ta solution.
    Grand merci Sai.

  12. #12
    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
    Avec les fonctions anlytiques, je pense que c'est plus facile.
    Après faut voir avec les 2 Millions de lignes
    Moi j'avais fait ça avant de me faire griller par remi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT DISTINCT 
    		nom, 
    		FIRST_VALUE(dte_deb) OVER (PARTITION BY nom ORDER BY dte_deb DESC) AS date_deb, 
    		FIRST_VALUE(dte_fin) OVER (PARTITION BY nom ORDER BY dte_deb DESC) AS date_fin
    FROM MaTable
    J'ai testé, les 2 marchent.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    Puissant tout ça, diantre il y en a à apprendre
    Merci

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    401
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 401
    Points : 120
    Points
    120
    Par défaut
    Merci pour ces superbes solutions

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

Discussions similaires

  1. Requête (casse tête)
    Par shadeoner dans le forum SQL
    Réponses: 24
    Dernier message: 23/05/2008, 14h23
  2. Requête (casse tête)
    Par shadeoner dans le forum Requêtes
    Réponses: 2
    Dernier message: 13/02/2008, 11h35
  3. Requête casse tête.. à vous de jouer.. :)
    Par chriscoolletoubibe dans le forum Hibernate
    Réponses: 3
    Dernier message: 17/09/2007, 10h39
  4. requête casse-tête pour une seule table..
    Par MikeV dans le forum Requêtes
    Réponses: 9
    Dernier message: 23/08/2007, 22h02
  5. Requête casse tête!
    Par sonorc dans le forum Langage SQL
    Réponses: 10
    Dernier message: 08/05/2007, 03h03

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