Requête sql avec deux fois une référence à un champ extérieur

Messages postés
4
Date d'inscription
lundi 10 décembre 2018
Statut
Membre
Dernière intervention
13 décembre 2018
- - Dernière réponse : Sylvain_ok_gnagna
Messages postés
4
Date d'inscription
lundi 10 décembre 2018
Statut
Membre
Dernière intervention
13 décembre 2018
- 13 déc. 2018 à 12:31
Bonjour,

J'utilise Access 2007 pour MS Visual Studio Express 2017 sous Windows pour faire un programme personnel
pour mon épouse (opticienne) Après 20 ans sous VB 5, je découvre (enfin) le multitable.

Je donne ici un exemple (simplifié, pour ma question) qui fonctionne (avec le vendeur, sans le livreur) me limitant autant que possible au SQL :
Le but de cette requête (deux tables) est de dresser la liste des visites d'un client.
L'enregistrement d'une visite comprend, entre autres, la référence du vendeur (qui vend les lunettes) et celle du livreur
(qui livre les lunettes au magasin lorsque le client revient les chercher)
La table Visites comprend les paramètres d'une visite, et la table Users ceux d'un utilisateur du programme (Vendeur ou livreur)


' 1) Exemple qui fonctionne, qui ne cherche que le vendeur (pas le livreur)
Dim sql As String = ""

sql &= "SELECT v.*, u.Initiales AS Vendeur "
sql &= "FROM Visites v, Users u "
sql &= "WHERE Client_num = " & Client_num & " "

sql &= "AND u.Initiales IN("
sql &= " SELECT u.Initiales"
sql &= " FROM Users u"
sql &= " WHERE u.User_num = v.CréationEnrgt_User_num"
sql &= " )"

----------------------------------------------------------------------------------------------

' 2) Exemple qui NE fonctionne PAS, qui cherche le vendeur ET le livreur
Dim sql As String = ""

sql &= "SELECT v.*, u.Initiales AS Vendeur , u.Initiales AS Livreur "
sql &= "FROM Visites v, Users u "
sql &= "WHERE Client_num = " & Client_num & " "

sql &= "AND u.Initiales IN("
sql &= " SELECT u.Initiales"
sql &= " FROM Users u"
sql &= " WHERE u.User_num = v.CréationEnrgt_User_num"
sql &= " )"

sql &= "AND u.Initiales IN("
sql &= " SELECT u.Initiales"
sql &= " FROM Users u"
sql &= " WHERE u.User_num = v.Livr_User_num"
sql &= " )"


QUESTION : dans Visites se trouvent les deux utilisateurs à rechercher (mêmes champs) Mais comment les distinguer dans la sql ?

Bonjour si quelqu'un est assez calé pour le savoir, mais merci d'avance.
Afficher la suite 

6 réponses

Messages postés
14565
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
13 octobre 2019
136
0
Merci
A la place d'appeller 2 fois ta table :
Users u
Essayes de faire la première fois :
Users u
puis
Users u1

Comme ça, 2 noms différents et pas de soucis.
Commenter la réponse de NHenry
Messages postés
4
Date d'inscription
lundi 10 décembre 2018
Statut
Membre
Dernière intervention
13 décembre 2018
0
Merci
Bonjour,

Merci beaucoup pour ces explications. Je planche dessus, mais sans m'en sortir : je n'ai pas compris l'esprit de SQL.
Il y a de nombreux sites à ce sujet, mais sur chaque instruction, pas sur le "fonctionnement", "l'analyse" par SQL.
Je suis surpris qu'on puisse nommer une même table de deux alias. J'essaie avec ceci :

Dim sql As String = ""

' BLOC 1 :
sql &= "SELECT v.*, u.Initiales AS Vendeur , u1.Initiales AS Livreur "
sql &= "FROM Visites v, Users u , Users u1 "
sql &= "WHERE Client_num = " & Client_num & " "

' BLOC 2 :
sql &= "AND u.Initiales IN("
sql &= " SELECT u.Initiales"
sql &= " FROM Users u"
sql &= " WHERE u.User_num = v.CréationEnrgt_User_num"
sql &= " )"

' BLOC 3 :
sql &= "AND u1.Initiales IN("
sql &= " SELECT u1.Initiales"
sql &= " FROM Users u1"
sql &= " WHERE u1.User_num = v.Livr_User_num" ' (diverses versions, Cf. ci-dessous)
sql &= " )"

' version A : sql &= " WHERE u1.User_num = v.Livr_User_num AND v.Livr_User_num > 0" affiche 8 visites au lieu de 11; les visites sans livraison sont ignorées.
' version B : sql &= " WHERE u1.User_num = v.Livr_User_num" idem
' version C : sql &= " WHERE u1.User_num = v.Livr_User_num OR v.Livr_User_num = 0" affiche 23 visites au lieu de 11; chacune des 3 visites sans livraison paraissent 5 fois (1 par user existant)


QUESTION : sachant que ce client test n'a que 11 visites (vérifié en VB plus 'long' mais plus facile à maîtriser pour moi, et de visu dans Access)
- les User_num vont de 1 à 5 (0 en table Visites si la livraison n'a pas encore eu lieu), ce qui explique que les versions A et B ne donnent que 8 visites
- la version C, pour chacune des 3 visites sans livraisons, renvoie 5 exemplaires d'une même visite (1 par user)
- je m'attendais à ceci : "dresser la liste des visites du client Client_num" + "ajouter les initiales du vendeur et du livreur prises dans la table Users", sans retrancher ni ajouter de lignes.

Alors j'ai imaginé ceci, à la place du bloc 3 :
sql &= " CASE"
sql &= " WHEN v.Livr_User_num = 0 THEN ''"
sql &= " WHEN v.Livr_User_num > 0 THEN "

sql &= " AND u1.Initiales IN("
sql &= " SELECT u1.Initiales"
sql &= " FROM Users u1"
sql &= " WHERE u1.User_num = v.Livr_User_num"
sql &= " )"

sql &= " END"

Merci d'avance pour vos aimables explications.
Commenter la réponse de Sylvain_ok_gnagna
Messages postés
4
Date d'inscription
lundi 10 décembre 2018
Statut
Membre
Dernière intervention
13 décembre 2018
0
Merci
Pour que les 3 visites sans livraison soient affichées, j'ai créé un utilisateur de User_num = 0 avec des initiales vide ("") Ainsi, il sera trouvé par la partie "WHERE u1.User_num = v.Livr_User_num", ce qui me semble être un artifice.
Ca ne me dit pas comment sql fonctionne...
Commenter la réponse de Sylvain_ok_gnagna
Messages postés
26489
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
14 octobre 2019
316
0
Merci
Bonjour,

Ne connais tu pas les Jointures LEFT / RIGHT .. ?
https://support.office.com/fr-fr/article/op%C3%A9rations-left-join-right-join-ebb18b36-7976-4c6e-9ea1-c701e9f7f5fb

En gros :
SELECT T.* ,
   U.nom as nom_livreur,
   U2.nom as nom_vendeur,
FROM table T
LEFT JOIN utilisateur U  ON U.id = T.id_livreur
LEFT JOIN utilisateur U2  ON U2.id = T.id_vendeur

Commenter la réponse de jordane45
Messages postés
26489
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
14 octobre 2019
316
0
Merci
NB: Pour poster du code sur le forum, merci de le faire en utilisant LES BALISES DE CODE (et en y précisant le langage)
Explications disponibles ici : https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

Commenter la réponse de jordane45
Messages postés
4
Date d'inscription
lundi 10 décembre 2018
Statut
Membre
Dernière intervention
13 décembre 2018
0
Merci
Malheureusement, non, je ne connais pas les jointures; je m'y suis intéressé hier et ai pensé (par erreur apparemment) que ce n'était pas la solution, pensant que ça doit cumuler des enregistrements (au lieu de seulement placer le nom du vendeur à la place de son code)

Je vais acheter de l'aspirine et ensuite je m'y colle...
Commenter la réponse de Sylvain_ok_gnagna