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

Langage SQL Discussion :

Aide pour faire une requette SQL


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 19
    Points : 14
    Points
    14
    Par défaut Aide pour faire une requette SQL
    Bonjour

    Bonjour tout le monde

    Voila j ai un petit souci pour faire une requette SQL d'oracle

    On a 2 tables Jobs et Employees comme suit:

    Dans la table Employee on a les champs: Employee_id , Job_id
    Dans la table Jobs on a le champs Job_Id

    Chaque employé a un job évidement.

    La question est de trouver le job qui a le plus d'employées autrement dit le job le plus occupé

    SVP si vous pouvez m'aider

    Merci beaucoup

  2. #2
    Membre actif Avatar de Jihnn
    Inscrit en
    Décembre 2005
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 330
    Points : 273
    Points
    273
    Par défaut
    Bonjour,

    L'idée est de récupérer le nombre d'employés par job, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT Job_id, COUNT(*) as employeesByJob
    FROM Employee
    GROUP BY Job_id;
    Pour récupérer le employeesByJob le plus grand, il y a plusieurs solutions. Je ne travaille pas avec Oracle, mais j'ai entendu parler de rownum qui pourrait être intéressant, mais je ne suis pas exactement certain de son fonctionnement. Je crois que ça serait comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT Job_id, employeesByJob
    FROM 
        (
            SELECT Job_id, COUNT(*) as employeesByJob
            FROM Employee
            GROUP BY Job_id
            ORDER BY employeesByJob DESC
        ) a
    WHERE rownum = 1
    Sinon, tu peux utiliser les fonctions analytiques mais à priori, rownum fonctionne de la même façon que rank() dans ce cas-ci (et devrait être plus rapide logiquement).

  3. #3
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 19
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Jihnn Voir le message
    Bonjour,

    L'idée est de récupérer le nombre d'employés par job, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT Job_id, COUNT(*) as employeesByJob
    FROM Employee
    GROUP BY Job_id;
    Pour récupérer le employeesByJob le plus grand, il y a plusieurs solutions. Je ne travaille pas avec Oracle, mais j'ai entendu parler de rownum qui pourrait être intéressant, mais je ne suis pas exactement certain de son fonctionnement. Je crois que ça serait comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT Job_id, employeesByJob
    FROM 
        (
            SELECT Job_id, COUNT(*) as employeesByJob
            FROM Employee
            GROUP BY Job_id
            ORDER BY employeesByJob DESC
        ) a
    WHERE rownum = 1
    Sinon, tu peux utiliser les fonctions analytiques mais à priori, rownum fonctionne de la même façon que rank() dans ce cas-ci (et devrait être plus rapide logiquement).
    Le soucis est que je souhaite faire les 2 en une seule requête donc compter le nombre d employés par job ensuite avoir le job qui a plus grand nombre d employé tout en une seule requête.

    Merci

  4. #4
    Membre actif Avatar de Jihnn
    Inscrit en
    Décembre 2005
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 330
    Points : 273
    Points
    273
    Par défaut
    C'est en une seule requête, j'ai simplement expliqué la démarche pour arriver à la requête pour que la prochaine fois, tu sois en mesure de trouver la requête par toi-même.

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 872
    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 872
    Points : 53 034
    Points
    53 034
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Jihnn Voir le message
    ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT Job_id, employeesByJob
    FROM 
        (
            SELECT Job_id, COUNT(*) as employeesByJob
            FROM Employee
            GROUP BY Job_id
            ORDER BY employeesByJob DESC
        ) a
    WHERE rownum = 1
    Cette requête ne correspond à aucun élément connu de SQL. Elle est donc fausse. D'ou tirez vous rownum ?
    Sachez en outre que la claude ORDER BY est illicite dans les sous requêtes.
    Enfin même dans le cas fortuit ou elle marcherait dans un SGBDR faisant du grand n'importe quoi, elle est susceptible de donner de faux résultats.
    Bref, une requête particulièrement imbécile, preuve que vous n'avez rien compris aux principes ensembliste qui sont le fondement des bases de données relationnelles.

    Une solution simple, parmi d'autres est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT Job_id
    FROM   Employee
    GROUP  BY Job_id
    HAVING COUNT(*) = (SELECT MAX(N)
                       FROM   (SELECT COUNT(*) AS N
                               FROM   Employee
                               GROUP  BY Job_id
                              ) AS T
                      )
    Autre façon de faire, avec le quantificateur ALL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT Job_id
    FROM   Employee
    GROUP  BY Job_id
    HAVING COUNT(*) >= ALL  (SELECT COUNT(*) AS N
                             FROM   Employee
                             GROUP  BY Job_id
                            ) AS T
    Plus sophistiqué avec les fonctions de ranking (norme SQL:2003)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT Job_id
    FROM   (SELECT Job_id, 
                   RANK() OVER (ORDER BY COUNT(*) DESC PARTITION BY Job_id) AS N
            FROM   Employee) AS T
    WHERE  N = 1
    Enfin, pour expliquer pourquoi la requête qui vous a été donné est fausse, il suffit de prendre un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (1, 100);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (2, 100);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (3, 200);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (4, 200);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (5, 300);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (6, 400);
    Dans votre cas la requête pondue donnera arbitrairement le job id 100 ou 200 (indéterminisme) puisqu'ils ont le même nombre d'employé et que c'est bien le maximum.
    Or en matière de SGBDR l'arbitraire ne peut exister !

    Conclusion : apprenez le langage SQL et les principes des SGBRD. Mon site web, comme mes livres peuvent vous y aider !

    A +

  6. #6
    Membre actif Avatar de Jihnn
    Inscrit en
    Décembre 2005
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 330
    Points : 273
    Points
    273
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Cette requête ne correspond à aucun élément connu de SQL. Elle est donc fausse. D'ou tirez vous rownum ?
    Du site d'Oracle (par exemple ici). Si j'ai bien compris (je n'ai malheureusement pas Oracle pour tester), c'est en gros l'équivalent de ROW_NUMBER() OVER(ORDER BY colonne quelconque). Ne sachant pas comment faire sans sous-requête pour récupérer le nombre d'employés par job en même temps que son rang, j'ai préféré procédé ainsi.
    Je n'avais effectivement pas pensé au cas où deux jobs auraient le même nombre d'employés, donc ROW_NUMBER() ne serait pas aussi approprié que rank()

    Sachez en outre que la claude ORDER BY est illicite dans les sous requêtes.
    Enfin même dans le cas fortuit ou elle marcherait dans un SGBDR faisant du grand n'importe quoi, elle est susceptible de donner de faux résultats.
    Oui, je m'en doutais

    Bref, une requête particulièrement imbécile, preuve que vous n'avez rien compris aux principes ensembliste qui sont le fondement des bases de données relationnelles.
    Un peu de respect n'a jamais tué personne. Nous n'avons pas tous eu la chance d'avoir des formations poussées dans ce domaine.

    Conclusion : apprenez le langage SQL et les principes des SGBRD. Mon site web, comme mes livres peuvent vous y aider !
    J'ai cherché à acheter votre livre, il ne semble pas disponible dans les magasins au Québec. Il n'est plus disponible chez Amazon ni chez Fnac selon mes recherches.

    http://www.amazon. fr/exec/obidos/ASIN/2744073180/wwwdeveloppec-21
    http://livre.fnac.com/a1236888/Frede...=1&Mn=-1&Ra=-1

  7. #7
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 19
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Cette requête ne correspond à aucun élément connu de SQL. Elle est donc fausse. D'ou tirez vous rownum ?
    Sachez en outre que la claude ORDER BY est illicite dans les sous requêtes.
    Enfin même dans le cas fortuit ou elle marcherait dans un SGBDR faisant du grand n'importe quoi, elle est susceptible de donner de faux résultats.
    Bref, une requête particulièrement imbécile, preuve que vous n'avez rien compris aux principes ensembliste qui sont le fondement des bases de données relationnelles.

    Une solution simple, parmi d'autres est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT Job_id
    FROM   Employee
    GROUP  BY Job_id
    HAVING COUNT(*) = (SELECT MAX(N)
                       FROM   (SELECT COUNT(*) AS N
                               FROM   Employee
                               GROUP  BY Job_id
                              ) AS T
                      )
    Autre façon de faire, avec le quantificateur ALL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT Job_id
    FROM   Employee
    GROUP  BY Job_id
    HAVING COUNT(*) >= ALL  (SELECT COUNT(*) AS N
                             FROM   Employee
                             GROUP  BY Job_id
                            ) AS T
    Plus sophistiqué avec les fonctions de ranking (norme SQL:2003)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT Job_id
    FROM   (SELECT Job_id, 
                   RANK() OVER (ORDER BY COUNT(*) DESC PARTITION BY Job_id) AS N
            FROM   Employee) AS T
    WHERE  N = 1
    Enfin, pour expliquer pourquoi la requête qui vous a été donné est fausse, il suffit de prendre un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (1, 100);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (2, 100);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (3, 200);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (4, 200);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (5, 300);
    INSERT INTO Employee (Employee_id , Job_id)
    VALUES (6, 400);
    Dans votre cas la requête pondue donnera arbitrairement le job id 100 ou 200 (indéterminisme) puisqu'ils ont le même nombre d'employé et que c'est bien le maximum.
    Or en matière de SGBDR l'arbitraire ne peut exister !

    Conclusion : apprenez le langage SQL et les principes des SGBRD. Mon site web, comme mes livres peuvent vous y aider !

    A +
    Bonjour

    Merci beaucoup de votre aide la requête marche parfaitement et j ai choisis votre 1ere proposition mais il me reste encore une chose a régler car en fait la table jobs contient job_id et job_title et je souhaite afficher aussi le job_title mais je n'arrive pas a faire une jointure.

    Je vous remercie encore une fois.

  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 872
    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 872
    Points : 53 034
    Points
    53 034
    Billets dans le blog
    6
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT J.*
    FROM   Jobs AS J
    WHERE  Job_Id IN (SELECT Job_id
                      FROM   Employee
                      GROUP  BY Job_id
                      HAVING COUNT(*) = (SELECT MAX(N)
                                         FROM   (SELECT COUNT(*) AS N
                                                 FROM   Employee
                                                 GROUP  BY Job_id
                                                ) AS T
                                       )
    Par exemple !

    Lisez ce que j'ai écrit au sujet des sous requêtes : http://sqlpro.developpez.com/cours/sqlaz/sousrequetes/

    A +

  9. #9
    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 386
    Points
    18 386
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Cette requête ne correspond à aucun élément connu de SQL. Elle est donc fausse. D'ou tirez vous rownum ?

    Sachez en outre que la claude ORDER BY est illicite dans les sous requêtes.
    Enfin même dans le cas fortuit ou elle marcherait dans un SGBDR faisant du grand n'importe quoi, elle est susceptible de donner de faux résultats.
    La façon d'écrire cette requête sous Oracle est l'équivalent du TOP sous SQL Server, "verrues" issues du temps où la norme ne couvrait pas ces besoins qui existent pourtant depuis le début.
    rownum est la pseudocolonne Oracle qui positionne le numéro de ligne du résultat, après le tri (ce qui explique l'utilisation d'une sous-requête).

    C'est sémantiquement correct. Vos remarques au sujet du déterminisme de cette requête sont 100% valides.

    Citation Envoyé par SQLpro Voir le message
    Plus sophistiqué avec les fonctions de ranking (norme SQL:2003)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT Job_id
    FROM   (SELECT Job_id, 
                   RANK() OVER (ORDER BY COUNT(*) DESC PARTITION BY Job_id) AS N
            FROM   Employee) AS T
    WHERE  N = 1
    PARTITION BY avant le ORDER BY, et il manque le GROUP BY dans la sous-requête.

  10. #10
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 19
    Points : 14
    Points
    14
    Par défaut
    Merci tout le monde pour votre aide et particulièrement à SQLpro.

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

Discussions similaires

  1. Aide pour construire une requête SQL
    Par squalito dans le forum Langage SQL
    Réponses: 3
    Dernier message: 09/03/2007, 14h08
  2. Réponses: 1
    Dernier message: 13/12/2006, 09h04
  3. aide pour faire une Div
    Par nebil dans le forum Mise en page CSS
    Réponses: 21
    Dernier message: 31/07/2006, 18h51
  4. demande d'aide pour faire un requete sql
    Par carmen256 dans le forum Requêtes
    Réponses: 3
    Dernier message: 14/04/2006, 09h50
  5. [VBA-E]besoin d'aide pour faire une boucle
    Par mikazounette dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 10/04/2006, 14h04

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