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 :

Encore une requête complexe sur plusieurs tables


Sujet :

Langage SQL

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 12
    Points : 8
    Points
    8
    Par défaut Encore une requête complexe sur plusieurs tables
    Bonjour tout le monde,

    Depuis quelques jours je tente de réaliser un requête qui me semble assez complexe, en tout cas pour moi. Je voudrais bien vous expliquer mon problème de façon simple et pas trop long, mais je crois que la complexité du problème m'oblige à donner le plus de détails possibles. Donc vous m'excuserai pour la longueur de ce message.

    Pour commencer voici une partie de la structure de ma table qui est sous Access 2000.

    T_Appel

    app_id numéro auto
    app_client_id numérique
    app_termine oui/non

    T_Appel_Desc

    app_desc_id numéro auto
    app_desc_app_id correspond avec T_Appel
    app_desc_emp_id_ref numérique


    T_Appel_Retour

    app_ret_id numéro auto
    app_ret_app_id correspond avec T_Appel
    app_ret_emp_id_ref numérique

    T_Appel_Service

    app_serv_id numéro auto
    app_serv_app_id correspond avec T_Appel
    app_serv_emp_id_ref numérique


    T_Appel_Activite

    app_act_id numéro auto
    app_act_app_id correspond avec T_Appel
    app_act_tbl_id numéro de la table où a eu lieu l'activité( par exemple 1 pour T_Appel_Desc)
    app_act_oper_id numéro de l'activité dans la table correspondante(par exemple 2 qui correspondrait avec app_desc_id de T_Appel_Desc)

    Disons que ceci est un résumé d'une partie ma de base de données. Question d'abréger un peu je n'ai pas mentionné tous les champs de chaque table. C'est pourquoi je semble avoir 3 tables quasiment identique, mais en fait chacune doit enregistrer des données différentes et c'est la raison pour quoi j'en ai 3. En fait j'ai 6 tables du même genre que celles-ci mais je ne croyais pas utile de toutes les énumérer.

    Pour essayer que ce soit le plus clair poosible pour vous, je vous explique le principe du programme. Sur réception d'un appel, le numéro du client s'enregistre dans T_Appel, la description de l'appel et l'employé à qui l'appel est référé s'engeristre dans T_Appel_Desc. Puisqu'une activité vient d'avoir lieu, dans T_Appel_Activité s'enregistre le numéro de l'appel, soit app_id, le numéro de la table, soit 1 pour désigner la table T_Appel_Desc, le numéro de l'activité, soit app_desc_id. Ensuite pour le retour d'appel, le numéro d'appel, soit app_id, et le numéro d'employé à qui est référé la suite de l'appel est enregistré dans T_Appel_Retour. L'activité est également enregistré dans T_Appel_Activite selon le même principe que précédemment. Le processus est donc le même pour chaque processus d'un appel.

    Donc ce que je souhaite obtenir par la requête que je tente de faire désespérément, c'est d'obtenir tous les appels qui ne sont pas classé terminé dont la dernière activité est référé à un employé en particulier. Je dois donc trouvé la dernière activité pour chaque appel de ma table T_Appel dans ma table T_Appel_Activite, ensuite aller voir dans mes tables T_Appel_Desc, T_Appel_Retour et T_Appel_Service si l'activité est référé à un employé en particulier.

    Espérant que les explications que je vous ai fourni seront assez claires pour vous permettre de me donner une piste de solution pour réaliser cette requête. S'il vous manque d'informations, dites-le et je vous donnerai plus de détails.

    Merci à l'avance pour votre précieuse aide.

    @ +
    Denis

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Bonjour tout le monde,

    Bon après une torture mentale soutenue, voici ce que j'ai réussi à réaliser de mieux pour obtenir ce que je désire. J'aurais bien aimé tout faire cela dans une seule requête, mais si je n'y parviens vraiment pas. Pour le moment je dois faire avec 3 requêtes.

    Voici mes requêtes

    Ma requête 1 qui me trouve la dernière activité pour chaque appel.

    Requête1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT app_act_app_id, max(app_act_id) AS act_id
    FROM T_Appel_Activite
    WHERE app_act_app_id IN (SELECT app_id FROM T_Appel WHERE app_termine = false)
    GROUP BY app_act_app_id
    Ma requête 2 qui me donne la table et le numéro d'activité pour chaque appel de ma requête 1

    Requête2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT Act.app_act_app_tbl_id, Act.app_act_id_oper
    FROM T_Appel_Activite AS Act 
    INNER JOIN Requete1 AS R1 
    ON R1.act_id = Act.app_act_id
    Et finalement ma requête 3 qui est une requête Union, qui elle me donne le numéro d'appel lorsque la dernière activité est référé à un employé en particulier afin d'obtenir le résultat que je désire.

    Requête3
    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
     
    SELECT app_desc_app_id as App_id FROM T_Appel_Desc
    WHERE app_desc_id 
    IN (SELECT app_act_id_oper FROM Requete2
    WHERE app_act_app_tbl_id = 1) 
    AND app_desc_emp_id_ref = 1
    UNION
    SELECT app_ret_app_id FROM T_Appel_Retour
    WHERE app_ret_id 
    IN (SELECT app_act_id_oper FROM Requete2
    WHERE app_act_app_tbl_id = 2) 
    AND app_ret_emp_id_ref = 1
    UNION
    SELECT app_serv_app_id as App_id FROM T_Appel_Service
    WHERE app_serv_id 
    IN (SELECT app_act_id_oper FROM Requete2
    WHERE app_act_app_tbl_id = 3) 
    AND app_serv_emp_id_ref = 1
    Maintenant, j'ai beau essayer de joindre ces 3 requêtes pour d'en former qu'une seule, je ne trouve aucune solution valable. Peut-être est-ce impossible de regrouper ces 3 requêtes en une seule, mais on m'a souvent dit qu'en programmation rien n'est impossible

    Alors si les experts SQL ont une solution à me proposer, je suis preneur

    Encore merci à l'avance de prendre le temps de vous pencher sur mon problème.

    @ +
    Denis

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    332
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2002
    Messages : 332
    Points : 502
    Points
    502
    Par défaut
    Souvent, la complexite des requetes ne reflete que le manque de flexibilite de la structure de la base...

    Ta structure n'est pas relationnelle.

    Ton entite primaire, c'est Appel. Toutes les autres sont des references.

    Si il y a un appel, alors il ne devrait se creer qu'un seul enregistrement.

    Appel_Id est cree. Puis on assigne une cle eloigne des tables DANS CETTE MEME TABLE. Pas le contraire.

    Je vais employer un exemple.

    Table Employe : Emp_ID, Emp_Nom
    Table Type_Appel : Type_ID, Type_Desc
    Table Activite_Appel : Activite_ID, Activite_Desc

    Table Appel : Appel_ID, Emp_ID, Type_ID, Activite_ID, TempsCreation

    On cherche donc:
    tous les appels qui ne sont pas classé terminé dont la dernière activité est référé à un employé en particulier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT T1.*
    FROM Appel T1
        INNER JOIN Employe T2 ON T1.Emp_ID = T2.Emp_ID
        INNER JOIN Type_Appel T3 ON T1.Type_ID = T3.Type_ID
        INNER JOIN Activite_Appel T4 ON T1.Activite_ID = T4.Activite_ID
    WHERE T3.Type_Desc <> "Terminé"
        AND T2.Emp_Nom = "Ma Tante Gertrude"
    Je comprends pas ce truc d'activite et employe, mais en tous les cas... cette requete te permettrait de trouver tous les appels non termines de ma tante Gertrude.

    Je ne comprends pas assez les besoins de la base pour me faire une idee concrete de la structure. Mais je peux dire que trop de developpeurs perdent leur temps parcequ'ils ne se sont pas donne la peine de bien struturer leurs donnees. Et de ce que j'entrevois, tu aurais tout a gagner a suivre une formation adequate en gestion de donnees ou bien d'engager un consultant pour planifier la structure de la base en fonction des besoins presents et futurs.


  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Bonjour Babyneedle,

    Bon au départ, je n'oserai pas dire que tout ce que je fais est parfait, je suis loin d'avoir cette prétention. Mais de là à dire que la structure de ma base n'est pas relationnelle, il y a peut-être une marge. Je suis bien d'accord qu'il y a moyen d'améliorer ma base, mais allons-nous devoir partir un débat sur le sujet. À moins que les principes même de la vie doivent être classé comme illogique et non relationnelle, et qu'il ne faut surtout pas les appliquer à la programmation.

    Il y a un vieux principe qui dit qu'il ne faut pas mettre tous ses oeufs dans le même panier. Tu m'excuseras mais la structure de ma base de données a été construite en fonction de ce principe, simplement question de mettre de l'ordre dans tout ça.

    Pourquoi tout le monde met de l'ordre partout dans ces choses, mais qu'aussitôt qu'on tente de faire la même chose dans une base de données, on se fait dire que tout est croche et qu'on doit revoir la structure. Je sépare seulement mes appels selon leur état et je me fais dire que je ne suis pas correct. Pourquoi je dois chercher une aiguille dans une meule de foin quand je pourrais très bien ranger mes aiguilles sur une pelotte à aiguille? Pourquoi je devrais chercher un oeuf brun dans un panier d'oeufs parmi tous les oeufs blancs, alors qu'il serait si simple de faire un panier d'oeufs blancs et un panier d'oeufs bruns? Et si à côté de mes paniers d'oeufs, j'ai une liste pour me dire que l'oeuf que je recherche se trouve dans le panier # 2 et bien là je suis encore plus dans le champ.(expression québécoise pour dire qu'on fait fausse route).

    Alors oui je veux bien admettre, que peut-être il puisse avoir place à l'amélioration dans la structure de ma base de données. Mais de là à dire que je dois mettre tous mes oeufs dans la même panier, c'est une autre histoire. Je ne sais pas pour vous, mais moi si je cherche un fichier particulier sur mon ordinateur, c'est beaucoup plus long de faire une recherche sur le disque dur en entier que de chercher directement dans le répertoire ou se trouve ce fichier. Je croyais que c'était de là qu'était né le principe même des base de données, ranger chaque chose à sa place pour en accélérer la recherche.

    C'est vrai que je peux classer tous mes appels dans une même table, tout comme je peux vous dire que j'habite au Québec. Donc si vous voulez me trouver, ce n'est pas long à dire si on compare cela à une requête. Trouve Denis au Québec. Bonne chance car c'est grand le Québec. Pourtant c'est exactement ce que je passe mon temps à entendre quand je parle de la structure de ma base de données. Par contre si je vous dit que j'habite à tel adresse sur telle rue dans telle ville au Québec, vous allez me trouver en un rien de temps. Mais évidemment la requête pour me trouver sera beaucoup plus complexe. Vous allez devoir vous rendre dans ma ville pour chercher la rue et ensuite chercher l'adresse. C'est vrai qu'avec ces données, la complexité de la requête reflète le manque de flexibilité de la structure de ma ville.

    Si je comprend le principe que certain voudrait me voir adopter, si vous auriez à faire une base de données pour faire le bottin de téléphone d'une ville, vous n'auriez qu'une seule et unique table puisque chaque adresse et numéro de téléphone est unique. De cette façon quand vous chercherai une personne dans le bottin vous commencerez à la première page et tournerez chacune des pages jusqu'à arriver sur la personne rechercher qui habite à une certaine adresse.

    Alors je suis désolé d'être à l'ordre pour facilité mes recherches, il semblerait que ce n'est pas ce qu'on appelle être normal, d'où le terme normalisé. Pour moi c'est tout à fait normal d'avoir ma facture de téléphone classé dans un dossier, qui lui est classé dans mon classeur, qui lui est dans mon bureau, qui lui est dans ma maison. J'ai beau chercher, me semble que tout est en relation pourtant. De cette façon, avec l'ordre que je m'impose, je ne cherche pas pendant des heures dans la maison pour retrouver ma facture.

    Pour conclure, la question que je pose, doit-on privilégié la facilité pour demeurer flexible ou doit-on opter pour l'ordre malgré la complexité qu'elle entraine. Chacun a sa façon de voir les choses on dirait bien.

    Le débat est lancé, bien que je voulais simplement de l'information sur une requête. Vous connaissez maintenant mon opinion sur l'ordre, ceux qui veulent me dire que j'ai tort, expliquez-moi pourquoi. Je demeure tout de même ouvert aux opinions des autres en autant qu'elles soient logiques.

    Bonne journée et encore merci à ceux qui se pencheront sur mon réel problème, soit ma requête. Je ne dis pas non aux améliorations, mais j'ai un peu de difficulté avec le désordre. Alors si les suggestions sont pour améliorer l'ordre de ma base, je n'ai aucune objection.
    Denis

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    332
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2002
    Messages : 332
    Points : 502
    Points
    502
    Par défaut
    Premierement, pour pouvoir s'ameliorer en informatique, il faut comprendre que les commentaires sont toujours diriges vers le code et non pas vers une ou des personnes, alors ne prends pas ca personnel.

    Deuxiement, je parle d'experience, je travaille sur 40 + bases contenant en moyenne une vingtaine de tables.

    Troisiement, je n'ai pas dit de tout mettre tes oeufs dans le meme panier.

    Ce que je dit, c'est qu'une base relationnelle comprend generalement trois elements: les tables entites (client, departement, employe, representant) qui representent la realite. Ensuite il y a les tables de reference (Couleur, Poste, status, langue, province) qui represente des listes fixes ou peu souvent modifiables. Et il y a de qui rend la base "relationelle", les tables de relations.

    Par exemple, J'ai une table de docteurs et une table de patients (je travaille dans le milieu pharmaceutique).

    Dans un monde parfait, un patient n'a qu'un docteur: relation One-To-Many. Mais la realite est differentte. Un patient peut lui aussi avoir plusieurs docteurs. Une relation Many-To-Many, c'est de la bouillie pour chats.

    Quelle est la solution? Une table appellee TDocteur_Patient donc les champs sont TDocteur_Patient_ID, Docteur_ID, Patient_ID, dtCreated

    De cette maniere, je peut gerer ces deux tables entites a partir de ma table relationelle.

    Or, et par la je ne veux en rien te denigrer, une des erreurs les plus frequentes chez les juniors est de vouloir forcer une structure relationelle sur une base qui n'en a pas besoin.

    De ce que je vois, tu n'as besoin que de ta table d'appels comme table entite et les autres table ne sont qu'en reference par rapport a celle-ci, donc eloignees.

    Prenons une relation One-To-Many comme Appel et Employe. Un employe effectue plusieurs appels. Mais un appel ne peut pas etre fait par deux employes. Si un autre employe fait un follow-up, il ne s'agit pas du meme appel. Peut-etre le meme probleme, mais pas le meme appel. Si un appel ouvre un dossier qui pourrait etre modifie par un autre employe en generant un autre appel, alors il faut creer une table Dossiers (ou Problemes, etc.) et mettre sa cle unique encore dans la table Appel.

    Si j'appelle pour changer mon addresse. Je genere l'appel 666 et le Dossier 222. Or j'ai oublie mon code postal. Je rappelle et je parle a un autre employe. L'employe clique et l'application cherche le dernier appel que m'est lie etn cherchant mon Client_ID dans la table Appel et en extrayant mon Dossier_ID (222) qui permet de retourner chercher mon dossier. L'Employe corrige mon adresse, change le statut de mon dossier et mon address dans Client. Un autre appel a ete genere.

    Parfois je fais des requetes SQL de plusieurs pages, qui travaillent sur plusieurs bases de donnees et des dizaines de tables. Sans aucun probleme parce que la structure de ces bases est correcte...

    Un exemple de l'importance de la preparation de la structure.

    Un employe a consolide 12 projets d'un meme client en un seul en creant un table maitresse afin de gerer les duplicatats. Or, il n'a pas juge bon d'importer les informations sur les medications des patients de ces projets. Quand est venue la requete de faire des rapports web sur la medication, plutot que de n'avoir a gerer que 12 requetes indepentantes OU une requete sur la table maitresse, il a fallut jongler entre les deux structures. Resultat: au lieu de prendre une demie journee de travail, cela a pris 3 jours a monter les rapports. Nos rapports precedents se rafraichissaient en moins de une seconde. Maintenat, ils prennent parfois une minute! A la fin de l'annee, ca sera preque une semaine de salaire gaspillee. Cela a ete tellement derangeant que nous avons planifie utiliser 2-3 journees completes pour importer l'information des medication a la base maitresse et ainsi corriger l'erreur de cet EX-employe (quand nous aurons le temps...). C'est pas si mal quand il y a 500 patients, mais quand on parle en terme de centaines de milliers, c'est de l'argent "pitche" par les fenetres...

    En tous les cas... Je te conseille encore de repenser a ta structure ou a engager quelqu'un pour le faire, cela va t'eviter de jongler avec SQL.


  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Ok j'ai changé la structure de ma base et effectivement c'est mieux ainsi. En tout cas jusqu'à présent.

    Merci pour vos conseils.

    @ +
    Denis

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

Discussions similaires

  1. [SQL] Requête complexe sur plusieurs tables
    Par BFH dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 21/09/2007, 16h21
  2. requêtes sql sur plusieurs tables
    Par zahiton dans le forum Langage SQL
    Réponses: 4
    Dernier message: 25/11/2005, 10h59
  3. [SQL] requêtes SQL sur plusieurs tables
    Par zahiton dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 24/11/2005, 16h32
  4. Requête complexe sur plusieurs table
    Par DenPro dans le forum Langage SQL
    Réponses: 13
    Dernier message: 25/11/2003, 17h50
  5. A propos d'une requête SQL sur plusieurs tables...
    Par ylebihan dans le forum Langage SQL
    Réponses: 2
    Dernier message: 14/09/2003, 16h26

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