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 :

De la question a la requete


Sujet :

Langage SQL

  1. #1
    Nouveau candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 2
    Par défaut De la question a la requete
    Bonjour,

    J'espere qu'une personne pourra eclairer ma lanterne.

    Bien que comprenant ceratins principes de base au sujets des bases de donnees relationnelles et de SQL (ainsi que de l'algebre lineaire), je n'ai jamais reussi a comprendre comment:

    1) Traduire, en utilisant une methodologie que je recherche, une question exprimee en langage naturel en une requete SQL

    2) Savoir quand utiliser une jointure ou bien alors une sous-requete ou une combinaison

    J'arrive a ecrire des requetes sur plusieurs tables mais parfois c'est plus de la "magie" que de la science et bien que la magie soit une activite interessante a plusieurs niveaux ce n'est pas vraiment sa place dans une application informatique . Et parfois cela ne donne pas le resultat escompte ! (voir exemple en fin de message).

    Pourriez-vous m'aider?

    Merci par avance pour tout effort qui sera apprecie de toute facon.

    Jean-Michel.

    Exemple de probleme:

    Table Propriete (PropId, PropAdresse, TypeBatId)
    Table TypeBatiment (TypeBatId, TypeBatDesc)
    Table ProprieteSinistres (PropSinId, PropId, SinDate)
    Table Sinistre(SinDate, SinHeure)
    Table ProprieteSinistresSources(PropSinId, SinSourceId)
    Table SinistreSource(SinSourceId, SinSourceDesc)

    Donc un enregistrement de la table Propriete peut avoir subi plusieurs sinistres, donc relie a plusieurs enregistrements de la table ProprieteSinistres.

    La table ProprieteSinistres est reliee a la table Propriete par la cle etrangere PropId.

    Un enregistrement de la table ProprieteSinistres est relie a un enregistrement de la table Sinistre par la cle etrangere SinDate.

    Un meme sinistre pour une propriete specifiee, peut avoir eu plusieurs sources.

    Exemple dans le cas d'une inondation l'eau peut venir en meme temps d'une riviere, etre remontee depuis le sol et avoir debordee des egouts.

    Ceci est enregistrer par l'intermediaire de la table ProprieteSinistresSources.

    La table TypeBatiment a ete cree de facon a pouvoir changer en une seule fois un type de batiment un peu a la maniere d'utilisation d'une variable dans un programme a la place d'une valeur "en dur".

    Un enregistrement de la table Sinistre peut avoir "touche" plusieurs propriete, ceci est enregistrer dans la table ProprieteSinistres.

    Le but est d'enregistrer tous les sinistres et toutes leurs sources pour toutes
    les proprietes et de pouvoir faire des requetes variees sur ces informations/donnees.

    J'ai donc construit une requete comme celle-ci (la requete finale implique encore plus de tables que les cinq donnees en exemple) qui en fait se termine par un produit cartesien ce qui n'est pas le but recherche.

    La question est:

    Lister toutes les proprietes touchees par un sinistre dont la date est specifiee en indiquant la date et l'heure du sinistre, l'adresse, le type de propriete ainsi que toutes les sources du sinistre pour chacune des proprietes.

    Ma requete, qui donne un produit cartesien :

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    SELECT 
       Sinistre.SinDate,
       Sinistre.SinHeure,
       Propriete.PropAdresse,
       TypeBatiment.TypBatDesc,
       SinistreSource.SinSourceDesc
     FROM 
     (
     (
       TypeBatiment INNER JOIN Propriete ON TypeBatiment   
       TypeBatId=Propriete.TypeBatId
     ) 
     INNER JOIN 
        ProprieteSinistres 
     ON 
        Propriete.PropId=ProprieteSinistres.PropId
     )
     INNER JOIN
     (
       SinistreSource
     INNER JOIN
       ProprieteSinistresSources
     ON  
       SinistreSource.SinSourceId=ProprieteSinistresSources.SinSourceId
     ) 
    ON
       ProprieteSinistresSources.SinDate=Sinistres.SinDate
    WHERE
      Sinistres.SinDate=x
    Order By
      Sinistre.SinDate,
      Sinistre.SinHeure,
      Propriete.PropAdresse,
      TypeBatiment.TypBatDesc,
      SinistreSource.SinSourceDesc
    ;

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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 454
    Par défaut
    Je ne pense pas que votre requête donne un produit cartésien.
    Vos propriétés et sinistres ressortent plusieurs fois car vous avez probablement régulièrement plusieurs sources pour un même sinistre.

    Voici votre requête légèrement ré-écrite :
    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
    20
    21
    22
    23
    24
    25
    26
    SELECT 
        Sinistre.SinDate,
        Sinistre.SinHeure,
        Propriete.PropAdresse,
        TypeBatiment.TypBatDesc,
        SinistreSource.SinSourceDesc
    FROM 
        TypeBatiment
        INNER JOIN Propriete
          ON Propriete.TypeBatId = TypeBatiment.TypeBatId
        INNER JOIN ProprieteSinistres 
          ON ProprieteSinistres.PropId = Propriete.PropId
        INNER JOIN Sinistre
          ON Sinistre.SinDate = ProprieteSinistres.SinDate
        INNER JOIN ProprieteSinistresSources
          ON ProprieteSinistresSources.PropSinId = ProprieteSinistres.PropSinId
        INNER JOIN SinistreSource
          ON SinistreSource.SinSourceId = ProprieteSinistresSources.SinSourceId
    WHERE
        Sinistres.SinDate = <parametre>
    Order By
        Sinistre.SinDate,
        Sinistre.SinHeure,
        Propriete.PropAdresse,
        TypeBatiment.TypBatDesc,
        SinistreSource.SinSourceDesc
    Déjà vous remarquerez que les parenthèses ne sont pas nécessaires, on y gagne en clarté.

    Par contre avant d'aller plus loin, en réécrivant votre requête j'ai remarqué que la description des tables que vous avez donnée ne correspond pas à cette dernière : pas de table Sinistre dans votre requête, pas de champ SinDate dans la table ProprieteSinistresSources.
    Pouvez-vous vérifier ceci ?

    Et si vous pouviez mettre quelques données (un pas de test léger) avec un résultat qui vous pose problème ce serait encore mieux.

  3. #3
    Nouveau candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 2
    Par défaut Merci
    Merci pour votre reponse.

    Je vais revoir les tables et champs car l'exemple propose est une traduction simplifiee de la structure de la base en construction.

    Je reviens vers vous et le forum (avec aussi un respect des regles du forum) tres bientot.

    En attendant, quelle methodologie utilisez-vous pour etablir le texte de votre requete SQL en partant du schema de la base et de la question/requete utilisateur posee?

    Merci encore

    Jean-Michel.

  4. #4
    Membre averti Avatar de anakronox
    Inscrit en
    Novembre 2007
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 49
    Par défaut
    Bonjour. Il n'y a pas vraiment de methodologies pour cela. En fait si tu dispose déjà de ton schéma (ou MCD) il est simple de savoir comment organiser ta requête.
    Par exemple si on te demande des données liées à une unique table, tu regardes ton schéma et tu ecris la requête correspondante.
    Aussi, pour les jointures, l'utilisateur demande généralement (pour ne pas dire tout le temps) des informations qui appartiennent à des tables différentes. Dans ce cas l'une des tables en question dispose de la clé primaire de l'autre table (appelée clé étrangère) sur laquelle s'effectue la jointure.
    Les associations porteuses de données fonctionnent sur ce principe.

    Un bon conseil tout de même: aide toi toujours de ton MCD car il te permet de bien constater les associations entre les tables.
    Tu peux aussi chercher des cours sur ce sujet. (Google est ton ami )

  5. #5
    Membre très actif Avatar de fally
    Homme Profil pro
    Développeur .Net / BI
    Inscrit en
    Novembre 2007
    Messages
    966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Développeur .Net / BI

    Informations forums :
    Inscription : Novembre 2007
    Messages : 966
    Par défaut
    Citation Envoyé par anakronox Voir le message
    Un bon conseil tout de même: aide toi toujours de ton MCD car il te permet de bien constater les associations entre les tables.
    et par suite du MLD, plus clair et plus simple

  6. #6
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Une remarque conceptuelle sur la description des tables qui est donnée dans le premier message :
    Table ProprieteSinistres (PropSinId, PropId, SinDate)
    Table Sinistre(SinDate, SinHeure)
    S'il y a plusieurs sinistres à la même date, on ne pourra plus faire la différence entre les propriétés touchées par tel ou tel autre sinistre.

    Le bon conseil dans les réponses qui ont été données : commencer par faire un MCD solide.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 042
    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 : 22 042
    Billets dans le blog
    6
    Par défaut
    La clause FROM qui permet la jointure des tables dessine un arbre de jointure comme je l'ai déjà exprimé mainte fois. A partir du graphique de votre MCD et MPD il est facile de trouver le sous réseau qui constitue l'arbre de jointure.
    http://sqlpro.developpez.com/cours/s...ointures/#LV-B

    Il faut toujours commencer par la clause FROM (et donc ses multiples JOIN), ensuite par la clause WHERE et pour terminer la clause SELECT.

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

Discussions similaires

  1. Question sur une Requete
    Par othon_oda dans le forum SQL
    Réponses: 7
    Dernier message: 15/02/2007, 16h03
  2. Simple question concernant une requeTe
    Par unix27 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/11/2006, 22h11
  3. Question performance sur requetes sql
    Par shinrei dans le forum ASP
    Réponses: 7
    Dernier message: 19/05/2006, 13h28
  4. [VB2003][ACCESS] Question sur une requete
    Par Kanie dans le forum Langage SQL
    Réponses: 3
    Dernier message: 30/03/2006, 17h25
  5. question sur les requetes table héritée
    Par champion dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 30/08/2004, 14h19

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