CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

requete SQL interrogeant 3 tables

KodutFR
KodutFR
Niveau 7
19 mars 2013 à 19:31:00

Bonjour tout le monde,
Je me suis lancé il y a quelques semaines dans la création d'une base de donnée en partant de 0 (aucune connaissance sql). J'utilise open office base.

Je bloque depuis plusieurs heures sur quelque chose. Voici grosso modo comment est faite ma base (et merci à ceux qui prendront le temps de lire et de m'aider)
J'ai une table client contenant des informations sur mes clients (nom, telephone) qui sont tous des gérants d'entreprise (une personne peut avoir plusieurs entreprises)
une table entreprise qui contient des information sur les entreprises de mes clients
une table facture contenant les informations des factures que j'adresse aux entreprises de mes clients.

Je souhaite sortir un rapport contenant les informations suivantes : les noms des entreprises qui n'ont pas encore payé leur facture, le montant de leur dette (somme des montants des factures impayées - somme des accomptes versés) ainsi que les noms des gérants et leur numéro de téléphone. J'ai donc besoin des informations provenant de 3 tables différentes.
J'arrive a faire toutes les opérations (sommes et différences) mettre des critères (réglement = 0) grouper le tout par nom d'entreprise, mais je n'arrive pas à joindre les 3 tables entre elles. Par exemple dans une requete j'arrive a afficher les noms des entreprises endettées, le nom et prénom du gérant et son numéro de téléphone mais pas les informations de la table facture comme le montant de la dette. Ou inversement j'arrive à afficher les noms des entreprises et le montant de leur dette mais pas les informations de la table client comme le nom du gérant et son numéro de téléphone.

Comment je peux faire ?

Merci par avance

KodutFR
KodutFR
Niveau 7
19 mars 2013 à 20:10:26

En effet c'est ce que j'ai fait. Mais pour ce que je compte faire la jointure interne me parait la plus appropriée (a tort peut-etre)

Est-ce qu'il faut jouer au niveau des relations entre les tables ou bien au niveau des jointures dans la requete ?

Pseudo supprimé
Pseudo supprimé 19 mars 2013 à 20:17:06

Une meilleure référence : http://sqlpro.developpez.pez.com/cours/sqlaz/jointures/

godrik
godrik
Niveau 30
19 mars 2013 à 20:52:20

C'est une jointure (en fait 2) dans la requete qu'il te faut.

KodutFR
KodutFR
Niveau 7
19 mars 2013 à 21:02:55

j'ai joint le ID_entreprise de la table facture avec le ID_entreprise de la table entreprise, et j'ai également joint le ID_client de la table entreprise au ID_client de la table client

Je pensais que cela serait suffisant pour joindre le ID_client au ID_facture via le ID_entreprise. En gros il me manque une relation entre la table client et la table facture ?

godrik
godrik
Niveau 30
19 mars 2013 à 21:31:58

J'ai pas le temps de faire un cours complet de BD. Mais basiqumeent quand tu fais tes tables, tu mets dans chaque tables un champ (ou un ensemble de champ) qui sert (servent) a identifier uniquement une entree (appelle tuple ou n-uplet) dans la table. Cet (ces) identifiant(s) est (sont) souvent appelle cle primaire de la table.

Quand dans une table tu as besoin de faire reference a une entree dans une autre table, tu mets des champs dans la table qui servent a stocker la cle primaire de l'autre table. Ces champs sont appelle cle externe.
basiquement si tu as une table foo. Tu as un champ ID_foo et d'autre truc comme Nom ou je sais aps quoi. Si tu as une table bar qui reference la table foo, tu as un champ ID_bar pour identifier l'entree dans bar, mais tu as aussi un champ ID_foo pour reference l'entree correspondante dans la table foo.

Tu fais ta jointure "select * from foo, bar where bar.ID_foo = foo.ID_foo;"

_skip
_skip
Niveau 10
19 mars 2013 à 21:34:16

En fait tu dis qu'un client a plusieurs entreprise, puis une facture a une entreprise.

D'un point de vue modèle tu peux tout à fait passer d'une facture, et via l'entreprise retrouver le client. C'est seulement si l'entreprise a plusieurs clients tu es baisé.

Tu fais comme ceci :

de facture, tu joins entreprise sur la clé commune ID_entreprise.
De entreprise, tu joins client sur la clé commune ID_client.

Un exemple de requête :

Select
Client.nom_client,
Entreprise.raison_sociale,
facture.date_creation,
facture.montant_ouvert

FROM Facture
JOIN Entreprise on (facture.id_entreprise = Entreprise.id_entreprise)
JOIN Client on (Entreprise.id_client = client.idClient)

KodutFR
KodutFR
Niveau 7
20 mars 2013 à 19:33:32

OK merci pour vos réponses j'aurais du revenir un peu plus tot, j'ai cherché pendant 4 bonnes heures avant de trouver une solution. En fait j'ai créé deux requetes , puis j'ai basé une troisieme requete sur les résultats des deux premieres pour "piocher" les résultats que je voulais.

Je comprend toujours pas pourquoi j'arrivais pas à le faire en une seule requete.

Quelle serait la correspondance des lignes avec JOIN si on utilisait WHERE ? car je suis pas tres familiarisé avec la syntaxe JOIN

Pour mon un exemple un client peut avoir plusieurs entreprise, mais une entreprise ne peut etre gérées que par un seul client.

Je vais faire quelques essais encore, meme si je suis parvenu à ce que je voulais, j'aimerai bien en tirer des lecons et voir la "vraie" maniere de faire.

KodutFR
KodutFR
Niveau 7
20 mars 2013 à 19:55:04

voici le post que j'ai fait sur un autre forum, ca vous permettra d'y voir plus clair je pense :

T_client :
ID_client
nom_client
tel_client

T_entreprise :
ID_entreprise
ID_client
nom_entreprise

T_facture :
ID_facture
ID_entreprise
montant_facture
reglement_facture (oui/non)

La requete :
SELECT nom_entreprise, nom_client, tel_client, SUM( T_facture.montant_facture )
FROM T_entreprise, T_client, T_facture
WHERE T_entreprise.ID_client = T_client.ID_client
AND T_facture.ID_entreprise = T_entreprise.ID_entreprise
AND T_facture.reglement_facture = FALSE

le but est pour moi d'avoir les noms des entreprises n'ayant pas encore réglé leur facture, ainsi que le nom du client (qui est en fait le gérant de cette entreprise) et son numéro de téléphone, et la somme de tous les montants des factures impayées (d'ou le where reglement = false ou 0)

Ca ne fonctionne pas. Par contre si je n'utilise pas la fonction SUM ca marche mais le calcul n'est pas effectué et j'ai une ligne par facture non réglée, ce qui n'est pas ce que je souhaite (je veux vraiment afficher le total par entreprise). J'ai pensé à ajouter un GROUP BY sur ID_entreprise, mais sans succes.

_skip
_skip
Niveau 10
20 mars 2013 à 22:54:49

Il te manque les clauses du select dans ton group by.

SELECT nom_entreprise, nom_client, tel_client, SUM( T_facture.montant_facture )
FROM T_entreprise, T_client, T_facture
WHERE T_entreprise.ID_client = T_client.ID_client
AND T_facture.ID_entreprise = T_entreprise.ID_entreprise
AND T_facture.reglement_facture = FALSE
GROUP BY nom_entreprise, nom_client, tel_client

Sauf cas très particulier, toute colonne sélectionnée qui ne fait pas partie du calcul (ici SUM) doit être indiquée dans le group by.

KodutFR
KodutFR
Niveau 7
21 mars 2013 à 08:30:01

ah ok... Pourtant j'ai deja fait des requetes avec des calculs et des group by sur un seul champ il me semble que ca marchait.

Je suis pas chez moi la, j'essaierai ce soir ta solution. Mais en attendant si quelqu'un peut m'eclairer sur la logique de ce GROUP BY je veux bien, car je comprend pas pourquoi il faut mettre tous les champs

_skip
_skip
Niveau 10
21 mars 2013 à 09:25:15

KodutFR
Posté le 21 mars 2013 à 08:30:01
ah ok... Pourtant j'ai deja fait des requêtes avec des calculs et des group by sur un seul champ il me semble que ca marchait.

:d) Il y a des SGBD qui le tolèrent dans certains cas mais en principe c'est faux.

Ceci s'explique par le fait que pour que ta somme ait un sens
càd pour le cas qui nous concerne

[nom_entreprise, nom_client, tel_client, SUM(montant_facture )]

Il faut bien que les lignes qu'il te retourne en résultat soient uniques par sur la combinaison [nom_entreprise, nom_client, tel_client].

Si tu avais un résultat truc comme
IBM, Jean, +51 XXX, 1500
IBM, Jean, +51 XXX, 800
Oracle, Pierre, +21 YYY, 2000

Tu pourrais te demander pourquoi ce gros malin n'a pas groupé les 2 premières lignes IBM pour t'en retourner une seule avec 2300 comme somme puisqu'elles sont identiques?
C'est pour empêcher cela qu'on t'oblige à utiliser GROUP BY sur toutes les colonnes non "calculées".

KodutFR
KodutFR
Niveau 7
21 mars 2013 à 17:51:26

ok je comprend bien ce que tu veux dire.

Mais dans mon cas il ne peut y avoir qu'un client associé à une entreprise et un client ne peut avoir qu'un seul numéro de téléphone.

Donc a partir d'un groupement sur le nom de l'entreprise il ne pourra y avoir qu'un seul numéro de téléphone et qu'un seul nom client.

Sinon j'ai fait le test et ca fonctionne. par contre je ne suis qu'a moitié éclairé sur mes questions (c'est certainement moi qui ai du mal a comprendre)

_skip
_skip
Niveau 10
22 mars 2013 à 08:18:48

KodutFR
Posté le 21 mars 2013 à 17:51:26
ok je comprend bien ce que tu veux dire.

Mais dans mon cas il ne peut y avoir qu'un client associé à une entreprise et un client ne peut avoir qu'un seul numéro de téléphone.

:d) Oui mais ça c'est toi qui le sait parce que tu poses ces contraintes métier... Pas le SGBD. Il ne va pas décortiquer l'origine des colonnes du resultset, puis confronter celles-ci aux indexs ou foreign keys et en déduire tout seul que c'est forcément unique.

D'autant plus qu'il est possible d'aggréger des colonnes qui sont le résultat de fonction, ou faire des cross join de tes tables et là ça deviendrait vite fumeux pour lui de savoir avec certitude.

Retiens juste la chose suivante, tout ce qui est dans le SELECT et qui n'est pas calculé doit être dans GROUP BY. Le sgbd ne présume de rien en ce qui concerne la possible unicité des tuples.

KodutFR
KodutFR
Niveau 7
22 mars 2013 à 16:46:14

Super merci pour ces précisions _skip ! :ok:

Si j'ai de nouveau un probleme je reviendrai vous voir :D

Sous forums
  • Aide à l'achat Mac
  • Steam Deck
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Macintosh
  • Hardware
La vidéo du moment