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

Sylvain_ok_gnagna Messages postés 4 Date d'inscription lundi 10 décembre 2018 Statut Membre Dernière intervention 13 décembre 2018 - 11 déc. 2018 à 12:01
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.

6 réponses

NHenry Messages postés 15050 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 30 mars 2023 156
11 déc. 2018 à 18:43
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.
0
Sylvain_ok_gnagna Messages postés 4 Date d'inscription lundi 10 décembre 2018 Statut Membre Dernière intervention 13 décembre 2018
12 déc. 2018 à 15:20
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.
0
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 à 10:52
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...
0
jordane45 Messages postés 37295 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 1 avril 2023 341
13 déc. 2018 à 11:44
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

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jordane45 Messages postés 37295 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 1 avril 2023 341
13 déc. 2018 à 11:45
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

0
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
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...
0
Rejoignez-nous