rbellot
Messages postés9Date d'inscriptionmercredi 15 juillet 2009StatutMembreDernière intervention15 octobre 2010
-
2 sept. 2010 à 10:56
rbellot
Messages postés9Date d'inscriptionmercredi 15 juillet 2009StatutMembreDernière intervention15 octobre 2010
-
7 sept. 2010 à 08:08
Bonjour,
Je rencontre un problème de liaison de deux tables:
j'ai un première table qui contient des véhicules VEHIC et une autre table qui contient les enregistrements planning de ces véhicules.
Je souhaite pour une période donnée récupérer tous les enregistrement planning. Mais le problème est que je n'ai pas les véhicules qui ne sont pas utilisés au planning...et il me les faut.
Afin d'être optimal, j'ai créé une jointure et traité le problème du planning. Je cherche une solution élégante et performante (client/serveur)qui me permette d'y intégrer les véhicules absents du planning.
Une première piste est d'utiliser une requète intégrée : mais pas très optimale.
Une deuxième piste est de créer une deuxième requète derrière et de compléter la première: pas terrible non plus !
rbellot
Messages postés9Date d'inscriptionmercredi 15 juillet 2009StatutMembreDernière intervention15 octobre 2010 2 sept. 2010 à 11:48
Merci Casy
Genre:
Select
Planning.Id_Vehic
...
...
Vehic.Id_Vehic
...
...
From
Vehic Left outer join Planning on vehic.id_Vehic = planning.id_vehic
Where
planning.dateDebut >= pdatedebut and planning.dateFin <= pdatefin
Order by
...
Résultat : si les véhicules ne sont pas dans le planning ils n'apparaissent pas. Hors il me les faut, même à vide.
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 2 sept. 2010 à 14:11
Ok, je me suis un peu mélangé les pinceaux.
J'étais parti sur l'idée que les véhicules que tu ne vois pas n'avait pas du tout de planification. Or, ils ont bien des planifications mais en dehors de la plage souhaitée. Donc forcément ma requete ne marche pas.
Il faut effectivement des requetes imbriquées. La jointure se faisant ici, non pas sur la table planning, mais sur table temporaire ne contenant que les planifications dans la plage de date souhaité. D'ailleurs la jointure sera plutôt à ce moment là une externe droite :
SELECT P.Id_Vehic,...,V.Id_Vehic,..... FROM
(SELECT * FROM Planning
WHERE (Planning.dateDebut >= pdatedebut and
Planning.dateFin <= pdatefin)
) P
RIGHT OUTER JOIN Vehic V ON P.Id_Vehic=V.Id_Vehic
Attention, les champs "plannings" dans la clause SELECT ne viennent plus de la table Planning, mais de la table temporaire P
En espérant que cette fois-ci, ça marche
[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
rbellot
Messages postés9Date d'inscriptionmercredi 15 juillet 2009StatutMembreDernière intervention15 octobre 2010 2 sept. 2010 à 19:16
Merci casy de venir bruler tes neurones avec moi
Excuses moi mais j'étais chez un client cet AM.
Voici le code que j'ai testé
SELECT
v.id_VEHIC AS id_VEHIC,
V.NBR_PLACE AS NBR_PLACE,
V.VehicActif AS VehicActif,
V.VehicAFF AS VehicAFF,
V.catVehic AS catVehic,
V.id_TY_VEHI AS id_TY_VEHI,
V.Cle_Rang AS Cle_Rang,
V.dateSup AS dateSup,
V.PLQ_NUM AS PLQ_NUM,
V.desig50 AS desig50,
P.PGCLEUNIK AS PGCLEUNIK,
P.date_debut AS date_debut,
P.Heure_Debut AS Heure_Debut,
P.date_fin AS date_fin,
P.HEURE_FIN AS HEURE_FIN,
P.Lib_planning AS Lib_planning,
P.lib_survol AS lib_survol,
P.Typ_Mission AS Typ_Mission,
P.Cli_Option AS Cli_Option,
P.Id_MISSION AS Id_MISSION,
P.id_VEHIC AS id_VEHIC,
P.Id_M_Vehic AS Id_M_Vehic,
P.IDLg_Mission AS IDLg_Mission,
P.IDINTTECH AS IDINTTECH
FROM
(SELECT * FROM PLANNING_VEHIC
WHERE (PLANNING_VEHIC.date_debut >= {pDateDebut} AND
PLANNING_VEHIC.date_fin <= {pDateFin})
) P
RIGHT OUTER JOIN VEHIC V ON P.id_VEHIC = V.id_VEHIC
ORDER BY
id_VEHIC ASC
et le résultat est identique: aucun enregistrement ne remonte quand je paramètre un jour sans enregistrement dans la table planning_vehic.
Pourrais tu m'expliquer la différence entre jointure gauche et droite: j'ai cru comprendre une différence de cardinalité L(1,0) et R(1,+).
Par rapport à ton code ta requète sur le planning me parait bonne, par contre la recherche des véhicules absents dans la table planning et présents dans la table vehicule semble poser un problème.
Est ce que l'utilisation de is not ne serait pas une solution peut être dans une autre sous requète concernant les véhicules ? Ce n'est pas très élégant...
Ou l'élimination d'une intersection ?
rbellot
Messages postés9Date d'inscriptionmercredi 15 juillet 2009StatutMembreDernière intervention15 octobre 2010 2 sept. 2010 à 22:32
Bonsoir,
J'ai supprimé la clause order by et je teste :
Si je teste sur un jour où il n'y a aucun enregistrement dans le planning, donc la requète devrait ramener au moins les véhicules: le résultat est "pas d'enregistrement"
Si je teste sur un jour où il y a des enregistrements, il généère une erreur de code sql sur : pourquoi, je ne sais.
Dans tous les cas si j'ai bien compris ton code,le right outer join portant sur vehic ne peut me semble-t-il satisfaire la condition car elle n'existe pas, l'enregistrement côté planning étant absent. Peut être existe-t-il une clause absent, is not ??? unknown ???
Merci
Richard (je suis absent demain, je pourrai lire ta réponse mes pas la tester avant samedi matin)
Pour ce qui est de ta requete, l'absence de résultat ne vient pas (pour le moment en tout cas) d'un problème de jointure, mais simplement du fait que ta requete ne s'execute pas car elle comporte une erreur.
D'après le message que tu rapporte, ton moteur de base de donnée ne semble pas comprendre la syntaxe utilisée pour donner l'alias P à la requete intermédiaire.
Cette syntaxe marche telle quelle sous SQLServer. Je ne connais pas ton SGBD, mais il faudrait vérifier la syntaxe qu'il attend concernant les alias de tables.
[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
rbellot
Messages postés9Date d'inscriptionmercredi 15 juillet 2009StatutMembreDernière intervention15 octobre 2010 4 sept. 2010 à 18:43
Bonjour Casy,
Effectivement tu as raison le problème vient de l'alias de la table temporaire
(SELECT * FROM PLANNING_VEHIC
WHERE (PLANNING_VEHIC.date_debut >= {pDateDebut} AND
PLANNING_VEHIC.date_fin <= {pDateFin})
) P
J'ai essayé avec AS P mais cela ne change rien.
J'ai également changé le nom de l'alias en pensant à un conflit de nommage, mais idem.
Le SGBD est windev. On peut utiliser l'alias pour les rubriques et les tables mais viviblement pas pour une requète imbriquée. J'ai cherché aujourd'hui sur internet une explication mais je n'ai rien trouvé.
J'ai essayé ceci
(SELECT * FROM PLANNING_VEHIC
WHERE (PLANNING_VEHIC.date_debut >= {pDateDebut} AND
PLANNING_VEHIC.date_fin <= {pDateFin})
) P
VEHIC AS v
Dans ce cas il prend le from et propose un résultat.
Par contre dès que je rajoute la requète imbriquée et que j'utilise l'alias => erreur.
Vois tu une autre solution ? peut être deux requètes séparées : la première traitant le planning et la deuxième faisant le complément des véhicules ?
rbellot
Messages postés9Date d'inscriptionmercredi 15 juillet 2009StatutMembreDernière intervention15 octobre 2010 6 sept. 2010 à 19:31
Dernier essai !
J'ai donc développé un système à double requète ce n'est pas le + performant ni le plus élégant mais cela marche.
Mais comme je suis un gars têtu je poursuis néanmoins la recherche de la bonne solution (d'autant plus que j'ai plusieurs requêtes à faire sur cette architecture).
J'ai donc utilisé l'éditeur graphique de windev 14 pour réaliser la jointure externe, et voilà ci-dessous le code sql généré qui ne fonctionne pas plus, car les véhicules absents du planning, sont également absents de la requête.
SELECT
PLANNING_VEHIC.PGCLEUNIK AS PGCLEUNIK,
PLANNING_VEHIC.Date_Debut AS Date_Debut,
PLANNING_VEHIC.Heure_Debut AS Heure_Debut,
PLANNING_VEHIC.Date_Fin AS Date_Fin,
PLANNING_VEHIC.Heure_Fin AS Heure_Fin,
PLANNING_VEHIC.Lib_planning AS Lib_planning,
PLANNING_VEHIC.lib_survol AS lib_survol,
PLANNING_VEHIC.Typ_Mission AS Typ_Mission,
PLANNING_VEHIC.Cli_Option AS Cli_Option,
PLANNING_VEHIC.Id_MISSION AS Id_MISSION,
PLANNING_VEHIC.Id_VEHIC AS Id_VEHIC,
PLANNING_VEHIC.Id_M_Vehic AS Id_M_Vehic,
PLANNING_VEHIC.IDLg_Mission AS IDLg_Mission,
PLANNING_VEHIC.IDINTTECH AS IDINTTECH,
VEHIC.NBR_PLACE AS NBR_PLACE,
VEHIC.VehicActif AS VehicActif,
VEHIC.VehicAFF AS VehicAFF,
VEHIC.catVehic AS catVehic,
VEHIC.id_TY_VEHI AS id_TY_VEHI,
VEHIC.Cle_Rang AS Cle_Rang,
VEHIC.dateSup AS dateSup
FROM
VEHIC LEFT OUTER JOIN PLANNING_VEHIC ON PLANNING_VEHIC.Id_VEHIC = VEHIC.id_VEHIC
WHERE
(
PLANNING_VEHIC.Date_Debut >= pDateDebut
AND PLANNING_VEHIC.Date_Fin <= pDateFin
AND VEHIC.VehicActif = pVehicActif
AND VEHIC.VehicAFF = pVehicAff
AND VEHIC.dateSup = ''
)
ORDER BY
pRangementTyVehic ASC,
pRangementOperateur ASC,
pRangementAlpha ASC,
pRangementCapacite ASC,
Date_Debut ASC,
Heure_Debut ASC,
Id_VEHIC ASC
Un avis sur ce code ?
Merci pour vos réponses et idées diverses et variées qui pourraient faire avancer le débat.
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 6 sept. 2010 à 19:44
Non cette requete n'est pas bonne, car, comme on l'a vu, tu ne dois pas faire la jointure entre la table vehic et la table Planning, mais entre la table vehic et le résultat d'une première requete sur la table planning.
Je ne sais pas si tu peux le créer avec l'éditeur graphique, mais le cheminement c'est
- Faire une requete sur la table planning en filtrant sur ta plage de date
- Récupérer le résultat de cette requete comme une "table virtuelle" et faire une jointure externe droite avec la table vehic
Dommage que je puisse pas avoir windev pour pouvoir tester (bien que je n'ai pas d'à priori très positifs sur cet EDI, sans connaitre en plus).
[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
rbellot
Messages postés9Date d'inscriptionmercredi 15 juillet 2009StatutMembreDernière intervention15 octobre 2010 7 sept. 2010 à 08:08
Merci Casy
J'ai bien compris le sous ensemble mais je ne vois pas de solution pour le réaliser avec windev.
D'autre part dans une des docs windev il est dit clairement : "il est impossible d'effectuer des imbrications de jointures". Je ne sais pas très bien ce qu'ils entendent par là mais cela pourrait bien être les sous-ensembles en question.
Juste une petite question, lorsque l'on exécute une requète en C/S les données sont où : sur le serveur ou en local ?
En ce qui concerne windev c'est un très bon AGL, généralement il est très fort pour le cas général et permet de traiter le cas particulier avec des développements particuliers. Il existe assez peu de limites, celle ci en est une visiblement. Mais sans doute puis je contourner le pb par une autre architecture.