Précédent   Forum des professionnels en informatique > Environnements de développement > WinDev > HyperFileSQL
HyperFileSQL HyperFileSQL est un système de gestion de base de données relationnel exploité par les logiciels WinDev, WebDev et WinDev Mobile.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 09/01/2012, 15h01   #1
Membre actif
 
Inscription : juin 2006
Messages : 192
Détails du profil
Informations personnelles :
Âge : 26
Localisation : France, Hérault (Languedoc Roussillon)

Informations forums :
Inscription : juin 2006
Messages : 192
Points : 151
Points : 151
Envoyer un message via MSN à routmout
Par défaut [HF Classic][WD15] Requête dernier enregistrement par date (requêtes imbriquées)

Bonjour,

Malgré une recherche intensive (google, forum SQL) et l'aide de collègues, je me permet d'ouvrir une nouvelle discussion car je n'arrive pas à avancer et ceux depuis 2 jours ...

J'ai trois table : TBL_VOYAGE, TBL_LOT, TBL_VOYAGE_LOT

Je veux donc récupérer pour chaque LOT son dernier voyage, j'ai donc écrit ma requête suivante :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
SELECT
	*
FROM
	TBL_VOYAGE
INNER JOIN ...
WHERE
	TBL_VOYAGE.IDVOYAGE = 
(
SELECT
	TBL_VOYAGE.IDVOYAGE
FROM 
	TBL_VOYAGE
INNER JOIN
	TBL_LOT ON TBL_LOT.IDLOT = TBL_VOYAGE_LOT.IDLOT
INNER JOIN 
	TBL_VOYAGE_LOT ON TBL_VOYAGE.IDVOYAGE = TBL_VOYAGE_LOT.IDVOYAGE
WHERE
	TBL_VOYAGE.Date_VOYAGE = ( SELECT MAX(TMI.Date_VOYAGE) AS Date_VOYAGE FROM  TBL_VOYAGE AS TMI INNER JOIN TBL_VOYAGE_LOT AS TMU ON TMI.IDVOYAGE = TMU.IDVOYAGE WHERE TMU.IDLOT = TBL_LOT.IDLOT)
)
Bien sûr, je ne test que ma sous-requête :
Code :
1
2
3
4
5
6
7
8
9
10
11
 
SELECT
	TBL_VOYAGE.IDVOYAGE
FROM 
	TBL_VOYAGE
INNER JOIN
	TBL_LOT ON TBL_LOT.IDLOT = TBL_VOYAGE_LOT.IDLOT
INNER JOIN 
	TBL_VOYAGE_LOT ON TBL_VOYAGE.IDVOYAGE = TBL_VOYAGE_LOT.IDVOYAGE
WHERE
	TBL_VOYAGE.Date_VOYAGE = ( SELECT MAX(TMI.Date_VOYAGE) AS Date_VOYAGE FROM  TBL_VOYAGE AS TMI INNER JOIN TBL_VOYAGE_LOT AS TMU ON TMI.IDVOYAGE = TMU.IDVOYAGE WHERE TMU.IDLOT = TBL_LOT.IDLOT)
Le HExecuteRequete ne sort pas d'erreur, mais lorsque je passe sur le HlitPremier(), ma requête mouline et met 30 min à retourner 0 enregistrements.

J'ai changé dans ma sous-sous requête par :
Code :
1
2
 
SELECT TOP 1 TMI.Date_VOYAGE FROM  TBL_VOYAGE AS TMI INNER JOIN TBL_VOYAGE_LOT AS TMU ON TMI.IDVOYAGE = TMU.IDVOYAGE WHERE TMU.IDLOT = TBL_LOT.IDLOT ORDER BY TMI.Date_VOYAGE DESC
Le HexecuteRequete me retourne le message d'erreur "mot ORDER inatendu"

J'ai testé en HRequêteDefaut et en HRequeteSansCorrection, pas d'évolution...

Je pense que HFSql (ou Windev) ne sait pas interpréter le WHERE de ma 2nd sous-requête ...

Comment puis-je faire pour avoir les résultats attendu ?

Merci d'avance pour votre aide
__________________
RoUtMoUt DeVeLoPPeUr WINDEV FOU !!!!!!
routmout est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 11h16   #2
Membre actif
 
Inscription : juin 2006
Messages : 192
Détails du profil
Informations personnelles :
Âge : 26
Localisation : France, Hérault (Languedoc Roussillon)

Informations forums :
Inscription : juin 2006
Messages : 192
Points : 151
Points : 151
Envoyer un message via MSN à routmout
Suite à une demande sur le forum PCSOFT voici de meilleures explications

J'utilise en effet les sous-requêtes, je n'ai pas trop confiance avec les requêtes de requêtes

J'ai modifier mon code pour passer par une requête de l'éditeur : qSel_Parc_LOT, ça change pas grand chose mais le code est plus clair.

Mon code est :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
SI PAS HExécuteRequête(qSel_Parc_LOT,CnxFichiers,hRequêteSansCorrectionHF) ALORS
    //si pas HExécuteRequête(qSel_Parc_LOT,CnxFichiers,hRequêteSansCorrection) ALORS
    //si pas HExécuteRequête(qSel_Parc_LOT,hRequêteDéfaut) ALORS
    Info(HErreurInfo(hErrComplet))
    FIN
 
    HLitPremier(qSel_Parc_LOT)
    TANTQUE PAS HEnDehors(qSel_Parc_LOT)
    Trace(qSel_Parc_LOT.IDVoyage)
 
    HLitSuivant(qSel_Parc_LOT)
    FIN
 
    HAnnuleDéclaration(qSel_Parc_LOT)
En commentaire j'ai les différents paramètres testés. Les trois renvoi une erreur lorsque j’exécute la requête :

Code :
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
 
SELECT
TBL_LOT.IDLOT,
TBL_VOYAGE.Date_VOYAGE,
TBL_VOYAGE.IDVOYAGE,
TBL_Societe.Code_Societe,
TBL_Societe.Nom_Societe,
TBL_Chauffeur.Nom_Chauffeur,
TBL_Chauffeur.Prenom_Chauffeur,
TBL_LOT.Num_LOT
FROM
TBL_LOT
INNER JOIN
TBL_VOYAGE_LOT ON TBL_VOYAGE_LOT.IDLOT = TBL_LOT.IDLOT
INNER JOIN
TBL_VOYAGE ON TBL_VOYAGE.IDVOYAGE = TBL_VOYAGE_LOT.IDVOYAGE
INNER JOIN
TBL_Chauffeur ON TBL_Chauffeur.IDChauffeur = TBL_VOYAGE.IDChauffeur
INNER JOIN
TBL_Societe ON TBL_Chauffeur.IDSociete = TBL_Societe.IDSociete
INNER JOIN
( SELECT
TBL_VOYAGE_LOT.IDLOT,
Max(Date_VOYAGE) AS DateVOYAGE_Max
FROM TBL_VOYAGE
INNER JOIN
TBL_VOYAGE_LOT ON TBL_VOYAGE.IDVOYAGE = TBL_VOYAGE_LOT.IDVOYAGE
GROUP BY
TBL_VOYAGE_LOT.IDLOT
) AS ReqMaxDate ON TBL_VOYAGE_LOT.IDLOT = ReqMaxDate.IDLOT AND TBL_VOYAGE.Date_VOYAGE = ReqMaxDate.DateVOYAGE_Max
ORDER BY
TBL_VOYAGE.Date_VOYAGE
Mes messages d'erreur :
- En exécution par requête dans l'éditeur
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
Que s'est-il passé ?
 
Erreur DANS le code SQL DE la requête <qSel_Parc_LOT>. Initialisation DE la requête impossible.
 
Code Erreur : 70208
 
Niveau : Erreur Non fatale (EL_ONRETURN)
 
Code Erreur WD55 : 208
 
Dump DE l'Erreur du module 'WD150SQL.DLL' (15.00Cj).
 
Informations DE débogage :
 
IEWD150SQL=7.1
 
Module=<WD150SQL>
 
Version=<15.00Cj>
 
Informations supplémentaires :
 
EIT_LOGICALTABLENAME : <qSel_Parc_LOT>
- En passant par une Source De donnée et un HExecuteRequeteSQL de la requete écrite directement dans l'éditeur de code (requête contenu dans sReqParc_LOT.
Le HexecuteRequeteSQL n'engendre pas de message d'erreur cependant le HLitPremier oui :
Code :
1
2
3
4
5
6
 
SI PAS HExécuteRequêteSQL(sdParc_LOT,CnxFichiers,hRequêteSansCorrectionHF,sReqParc_LOT) ALORS
    //SI PAS HExécuteRequêteSQL(sdParc_LOT,CnxFichiers,hRequêteSansCorrection,sReqParc_LOT) ALORS
    //si pas HExécuteRequêteSuêteDéfaut,sReqParc_LOT) ALORS
    Info(HErreurInfo(hErrComplet))
    FIN
Message d'erreur :
Code :
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
 
Appel WL :
Traitement DE 'PROCEDURE LOCALE Remplit_tbmParc_LOT' (FEN_EtatParc.PROCEDURE.Remplit_tbmParc_LOT), ligne 131, thread 0
FONCTION 'HLitPremier', syntaxe 3
 
    Que s'est-il passé ?
    Fichier <qSel_Parc_LOT> inconnu DANS l'analyse <C:\Développement\Suivi_Chauffeur\Suivi_Chauffeur.wdd>, OU requête OU vue Non initialisée.
    SI il s'agit d'une requête, l'exécLOTon DE cette requête A peut-être échoué.
 
    Code Erreur : 70018
    Niveau : Erreur fatale (EL_FATAL)
    Code Erreur WD55 : 18
 
    Dump DE l'Erreur du module 'WD150HF.DLL' (15.00Hw).
    Identifiant des informations détaillées (.err) : 70116
    Informations DE débogage :
    IEWDHF=1.1
    Module=<WDHF>
    Version=<15.00Hw>
    FONCTION (7,10)
    Informations supplémentaires :
    EIT_PATHWDD : <C:\Développement\Suivi_Chauffeur\Suivi_Chauffeur.wdd>
    EIT_LOGICALTABLENAME : <qSel_Parc_LOT>
    EIT_PILEWL :
    PROCEDURE LOCALE Remplit_tbmParc_LOT (FEN_EtatParc.PROCEDURE.Remplit_tbmParc_LOT), ligne 131
    Clic SUR BTN_Rechercher (FEN_EtatParc.btn_Rechercher), ligne 2
    Sélection du menu DE _Menu.OPT_Administration.OPT_ETAT_PARC (FEN_Main._Menu.OPT_Administration.OPT_ETAT_PARC), ligne 1
    EIT_DATEHEURE : 11/01/2012 10:41:20
__________________
RoUtMoUt DeVeLoPPeUr WINDEV FOU !!!!!!
routmout est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 10h09   #3
Membre actif
 
Inscription : juin 2006
Messages : 192
Détails du profil
Informations personnelles :
Âge : 26
Localisation : France, Hérault (Languedoc Roussillon)

Informations forums :
Inscription : juin 2006
Messages : 192
Points : 151
Points : 151
Envoyer un message via MSN à routmout
Voici la réponse de =JBO= sur le forum PCSoft qui résout mon problème.

Un grand merci à lui


Bonjour routmout,

Après avoir fait des essais, je constate que le moteur HyperFile ne peut pas :
(a) gérer la jointure avec l'opérateur AND dans le dernier ON,
(b) gérer la condition dans une clause WHERE de même niveau (tu verras plus loin pourquoi je parle de niveau)

Et franchement, effectuer une jointure sur une colonne agrégée provenant d'une sous-requête agrégat, c'est assez complexe à gérer (j'imagine que d'autres SGBD y arrivent ?).

Alors je crois avoir trouver la parade.
Il faut que la condition sur la Date Max apparaisse dans une clause WHERE de plus haut niveau.
En clair, il faut ajouter un niveau d'imbrication de sous-requête.
Et pour exécuter la condition, il faut ajouter DateVOYAGE_Max dans la liste des rubriques retournées par la sous-requête "principale" afin de pouvoir comparer cette rubrique avec Date_VOYAGE.

La rubrique Date_VOYAGE est-elle indexée ?
Peut-être que ça peut améliorer les performances.

Code :
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
37
 
SELECT
*
FROM
 
( -- ---- début sous-requête principale ----
SELECT
 
TBL_VOYAGE.IDVOYAGE,
TBL_VOYAGE.Date_VOYAGE,
TBL_VOYAGE_LOT.IDLOT,
ReqMaxDate.DateVOYAGE_Max
 
FROM
(
( -- ---- début sous-requête GROUP BY ----
SELECT
TBL_VOYAGE_LOT.IDLOT,
Max(TBL_VOYAGE.Date_VOYAGE) AS DateVOYAGE_Max
FROM
TBL_VOYAGE INNER JOIN TBL_VOYAGE_LOT
ON TBL_VOYAGE.IDVOYAGE = TBL_VOYAGE_LOT.IDVOYAGE
GROUP BY
TBL_VOYAGE_LOT.IDLOT
) AS ReqMaxDate -- ---- fin sous-requête GROUP BY ----
 
INNER JOIN TBL_VOYAGE_LOT
ON ReqMaxDate.IDLOT = TBL_VOYAGE_LOT.IDLOT
)
 
INNER JOIN TBL_VOYAGE
ON TBL_VOYAGE_LOT.IDVOYAGE = TBL_VOYAGE.IDVOYAGE
 
) AS ReqPrincipale -- ---- fin sous-requête principale ----
 
WHERE
ReqPrincipale.DateVOYAGE_Max = ReqPrincipale.Date_VOYAGE
=JBO=
__________________
RoUtMoUt DeVeLoPPeUr WINDEV FOU !!!!!!
routmout est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 09h12.


 
 
 
 
Partenaires

Hébergement Web