OVH Cloud OVH Cloud

[WD 9] code SQL et temps d'exe

24 réponses
Avatar
JeAn-PhI
bonjour

voici le code sql d'une req :

SELECT *
FROM T_CLIENT
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_CLIENT.CL_ID in
(
SELECT T_CLIENT.CL_ID,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID

[
union
SELECT T_CLIENT.CL_ID,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID
]

)
ORDER BY T_CLIENT.CL_RAISON_SOCIALE ASC

1 - celle-ci s'execute en moins de 7 sec (très gros volume de données)
2 - si j'enlève tout ce qui est entre [] le temps passe à + de 20 sec

qq'un saurait me dire pourquoi car il me semble qu'elle devrait être
plus rapide dans le 2ème cas

--
Cordialement JeAn-PhI

10 réponses

1 2 3
Avatar
Emmanuel LECOESTER
la même avec union all au lieu de union
peut-être tenter des inner join plutot que des égalités. C'est la même chose
au final mais certains interpréteur préfère le inner join qui correspond à
la norme SQL.

"JeAn-PhI" a écrit dans le message de news:

JeAn-PhI avait écrit le 31/01/2007 :
bonjour

voici le code sql d'une req :


[CUT]

pour elecoest -> renvoi le résultat que je souhaite avec une rapidité
phénoménale - de 1 sec (il me reste encore du chemin à faire en SQL)

pour Frederic -> idem

pour Pierre -> renvoi le bon résultat mais en + de 2 sec


pour abuser un peu est ce qu'il y aurait moyen d'optimiser celle ci :

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE
union
SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID, CL_RAISON_SOCIALE
order by T_CLIENT.CL_RAISON_SOCIALE

le but étant d'avoir un liste qui contient 1 enreg pour un client avec la
somme des facture et ou 1 enreg pour le même client avec la somme des
avoirs
CLIENT1 SommeFacture
CLIENT1 SommeAvoir
CLIENT2 SommeFacture
CLIENT3 SommeAvoir
...

--
Cordialement JeAn-PhI





Avatar
JeAn-PhI
JeAn-PhI a écrit :
JeAn-PhI avait écrit le 31/01/2007 :
bonjour

voici le code sql d'une req :


[CUT]

pour elecoest -> renvoi le résultat que je souhaite avec une rapidité
phénoménale - de 1 sec (il me reste encore du chemin à faire en SQL)

pour Frederic -> idem

pour Pierre -> renvoi le bon résultat mais en + de 2 sec


pour abuser un peu est ce qu'il y aurait moyen d'optimiser celle ci :

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE
union
SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID, CL_RAISON_SOCIALE
order by T_CLIENT.CL_RAISON_SOCIALE

le but étant d'avoir un liste qui contient 1 enreg pour un client avec la
somme des facture et ou 1 enreg pour le même client avec la somme des avoirs
CLIENT1 SommeFacture
CLIENT1 SommeAvoir
CLIENT2 SommeFacture
CLIENT3 SommeAvoir
...



merci à tous je vais utiliser la solution de Frédéric car c'st ce que
je voulais faire mais comme je ne maitrise pas complètement SQL...

merci à tous

--
Cordialement JeAn-PhI
Avatar
JeAn-PhI
Emprin, Frederic a formulé la demande :
Bonsoir

pourquoi ne pas faire cela :

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total facture,
SUM(T_AVOIR_FACTURE.TOTAL) AS TotalAvoir

FROM T_CLIENT

LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}

LEFT JOIN T_AVOIR_FACTURE ON T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}

WHERE T_T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND (T_FACTURE.CL_ID is not null or T_AVOIR_FACTURE.CL_ID is not null)

GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE
order by T_CLIENT.CL_RAISON_SOCIALE

le but étant d'avoir un liste qui contient 1 enreg pour un client avec
la somme des facture et ou 1 enreg pour le même client avec la somme
des avoirs
CLIENT1 SommeFacture SommeAvoir
CLIENT2 SommeFacture SommeAvoir
CLIENT3 SommeFacture SommeAvoir

les sommes sont soit >0 toutes les deux soit une seule
on enleve les clients qui non rien

mais on a une ligne par client
maintenant si tu veux vraiement ton resultat sur une ligne fac et une ligne
avoir



[CUT]

je me suis réjouit trop vite les cumuls ne sont pas bon
après verif directement dans le fichier la somme des factures pour
plusieurs client est incohérente je cherche à comprendre

--
Cordialement JeAn-PhI
Avatar
Emprin, Frederic
Bonjour,

attention ans ce style e requette il faut faire attention
car je ne sais pas comment le moteur fait quand dans les somme il y a un
null
sur certain moteur l on met ifnull(macolonne,0) pour eviter les problemes

cela depend donc du moteur de base

"JeAn-PhI" a écrit dans le message de news:

Emprin, Frederic a formulé la demande :
Bonsoir

pourquoi ne pas faire cela :

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total facture,
SUM(T_AVOIR_FACTURE.TOTAL) AS TotalAvoir

FROM T_CLIENT

LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}

LEFT JOIN T_AVOIR_FACTURE ON T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}

WHERE T_T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND (T_FACTURE.CL_ID is not null or T_AVOIR_FACTURE.CL_ID is not null)

GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE
order by T_CLIENT.CL_RAISON_SOCIALE

le but étant d'avoir un liste qui contient 1 enreg pour un client avec
la somme des facture et ou 1 enreg pour le même client avec la somme
des avoirs
CLIENT1 SommeFacture SommeAvoir
CLIENT2 SommeFacture SommeAvoir
CLIENT3 SommeFacture SommeAvoir

les sommes sont soit >0 toutes les deux soit une seule
on enleve les clients qui non rien

mais on a une ligne par client
maintenant si tu veux vraiement ton resultat sur une ligne fac et une
ligne avoir



[CUT]

je me suis réjouit trop vite les cumuls ne sont pas bon
après verif directement dans le fichier la somme des factures pour
plusieurs client est incohérente je cherche à comprendre

--
Cordialement JeAn-PhI




Avatar
Emprin, Frederic
Re bonjour

attention aussi la requete que je t'ai donné ne fonctionnera que pour une
certaine cardinalite
c'est a dire elle fonctionnera si tes client ont une ou un avoir (ou pas) si
ta cardinalite est plus importante n facture, n avoir

il y a deux possibilites :
utiliser l'union que je t'ai donné
modifier la requete : en fait si tu enleve le group by tu verras :
si tu as un client qui a 2 facture et 3 avoir la requetes va remonter comme
ca:

CL1 500 300
CL1 400 300
CL1 400 200

donc pour le resultat tu dois avoir
CL1 900 800
hors le group by te renovi
CL1 1300 800

donc pour obtenir les bons chiffres la requete est un peu plus compliquée et
il faudrait des fonction comme IF case
et autre, mais le resultat comme ca est possible (aussi en sous requete etc
....)

mais le plus simple reste l'union et pour avoir tout sur une ligne mettre
cette union en jointure sur 2 requetes
(en fait utiliser chaque jointure comme une table et joindre les deux)

voila


"Emprin, Frederic" a écrit dans le message de
news: 45c22552$0$31793$
Bonjour,

attention ans ce style e requette il faut faire attention
car je ne sais pas comment le moteur fait quand dans les somme il y a un
null
sur certain moteur l on met ifnull(macolonne,0) pour eviter les problemes

cela depend donc du moteur de base

"JeAn-PhI" a écrit dans le message de news:

Emprin, Frederic a formulé la demande :
Bonsoir

pourquoi ne pas faire cela :

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total facture,
SUM(T_AVOIR_FACTURE.TOTAL) AS TotalAvoir

FROM T_CLIENT

LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}

LEFT JOIN T_AVOIR_FACTURE ON T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}

WHERE T_T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND (T_FACTURE.CL_ID is not null or T_AVOIR_FACTURE.CL_ID is not null)

GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE
order by T_CLIENT.CL_RAISON_SOCIALE

le but étant d'avoir un liste qui contient 1 enreg pour un client avec
la somme des facture et ou 1 enreg pour le même client avec la somme
des avoirs
CLIENT1 SommeFacture SommeAvoir
CLIENT2 SommeFacture SommeAvoir
CLIENT3 SommeFacture SommeAvoir

les sommes sont soit >0 toutes les deux soit une seule
on enleve les clients qui non rien

mais on a une ligne par client
maintenant si tu veux vraiement ton resultat sur une ligne fac et une
ligne avoir



[CUT]

je me suis réjouit trop vite les cumuls ne sont pas bon
après verif directement dans le fichier la somme des factures pour
plusieurs client est incohérente je cherche à comprendre

--
Cordialement JeAn-PhI








Avatar
JeAn-PhI
Emprin, Frederic a formulé la demande :
[CUT]

mais le plus simple reste l'union et pour avoir tout sur une ligne mettre
cette union en jointure sur 2 requetes
(en fait utiliser chaque jointure comme une table et joindre les deux)

voila




[CUT]
un petit exemple pour mieux comprendre svp

--
Cordialement JeAn-PhI
Avatar
Emprin, Frederic
Bonjour,

bon voici un exemple mais a condition que le moteur de base comme oracle ou
sqlserveur, mysql
accepte les sous requetes. averifier mais par experience je dirait qu'entre
l'union et cette requete le temps est presque identique. l'avantage est
d'avoir le resultat sur 1 seule ligne pour chaque client

SELECT TABLE1.CL_ID,TABLE1.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(TABLE1.TotalFacture) AS Total facture,
SUM(TABLE2.TotalAvoir) AS TotalAvoir

FROM

(SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS TotalFacture,

FROM T_CLIENT

LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}

WHERE T_T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND (T_FACTURE.CL_ID is not null )

GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE ) AS TABLE1

LEFT JOIN

(SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS TotalAvoir

FROM T_CLIENT

LEFT JOIN T_AVOIR_FACTURE ON T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}

WHERE T_T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND (T_AVOIR_FACTURE.CL_ID is not null)

GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE ) AS TABLE2

ON TABLE1.CL_ID = TABLE2.CL_ID

GROUYP BY TABLE1.TABLE1.CL_ID
ORCER BY TABLE1.CL_RAISON_SOCIALE

en fait le but etant de faire de chaque union une table comme si on creait
une temporary, mais avec les sous select
on peut le faire sans creer de table temporaire. chaque requete devient une
table et on fait simplement une jointure sur ces deux tables

cequi revient a avoir une table TABLE1 avec CL_ID,RAISON_SOCIAL,
SOMMEFACTURE et une TABLE2 avec CL_ID,RAISON_SOCIAL, SOMMEAVOIR
ensuite on fait une jointure sur ces deux tables pour avoir 1 lignes pour
chaque client avec les 2 sommes

je prend pour exemple un cas qui m'est arrivé dernierement. une requete qui
remontait en 244 secondes !
avec des or des in ce qui ne permetait pas d'utiliser l'index (du fait des
in et or les index ne sont pas complet et on a un parcours de la table
complete)
ou du moins sur une partie de l'index et non l'index complet meme en
fournissant la date par exemple dans un betwween qui arrete le parcours de
l'index avant la date. donc on parcours tous l'index et on verifie pour
chaque date alors qu'un = sur une date est instantané.

la requete a ete faite sur des unions de chaque date, mais l'inconvenient
est d'avoir une ligne par date. en faisant du resultat de cette requete une
table (du moin en mettant cette requete dans le FROM) et ensuite faire la
jonture a permis a cette requete de remonte en 3 secondes au lieu de 244 !!

bref si les sous select sont acceptés c'est une possibilite non negligeable.

je vous l'accorde la requete qui mettait 244 secondes faisait 50 lignes de
texte alors que la requete avec les unions sur chaque date (construite
dynamiquement par code :juste une boucle pour construire toutes les unions)
faisait 19 000 lignes !!!!! mais remontait en 3 secondes.

attention toute fois car le moteur interpretant ce genre de requete doit
être un vrai moteur
(on utilise un peu cette technique pour simuler le limit sur oracle ou
SQLserveur)

voila
Bon dv
@+

"JeAn-PhI" a écrit dans le message de news:

Emprin, Frederic a formulé la demande :
[CUT]

mais le plus simple reste l'union et pour avoir tout sur une ligne mettre
cette union en jointure sur 2 requetes
(en fait utiliser chaque jointure comme une table et joindre les deux)

voila




[CUT]
un petit exemple pour mieux comprendre svp

--
Cordialement JeAn-PhI




Avatar
JeAn-PhI
Emprin, Frederic a couché sur son écran :
Bonjour,

bon voici un exemple mais a condition que le moteur de base comme oracle ou
sqlserveur, mysql
accepte les sous requetes. averifier mais par experience je dirait qu'entre
l'union et cette requete le temps est presque identique. l'avantage est
d'avoir le resultat sur 1 seule ligne pour chaque client



[CUT]
après correction et modif pour adapter au moteur HF voici ce que ca
donne :

SELECT TABLE1.CL_ID as CL_ID,
TABLE1.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(TABLE1.TotalFacture) AS TotalFacture,
SUM(TABLE2.TotalAvoir) AS TotalAvoir

FROM (SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS TotalFacture
FROM T_CLIENT LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
AND (T_FACTURE.CL_ID is not null)
GROUP BY CL_ID,CL_RAISON_SOCIALE) AS TABLE1

LEFT JOIN

(SELECT T_CLIENT.CL_ID as CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS TotalAvoir
FROM T_CLIENT LEFT JOIN T_AVOIR_FACTURE ON T_AVOIR_FACTURE.CL_ID =
T_CLIENT.CL_ID
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
AND (T_AVOIR_FACTURE.CL_ID is not null)
GROUP BY CL_ID,CL_RAISON_SOCIALE) AS TABLE2

ON TABLE1.CL_ID = TABLE2.CL_ID

GROUP BY CL_ID,CL_RAISON_SOCIALE
ORDER BY CL_RAISON_SOCIALE

j'ai mis le test de la date dans la close WHERE car dans le LEFT JOIN
cela ne fonctionne pas dans ce cas

remarque :
le test de la date dans la close WHERE est plus rapide que dans le LEFT
JOIN

remarque 2 :
SELECT T_CLIENT.CL_ID AS CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_CLIENT LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE %{pClientRS}%
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
AND (T_FACTURE.CL_ID IS NOT NULL)
GROUP BY CL_ID, CL_RAISON_SOCIALE

UNION ALL

SELECT T_CLIENT.CL_ID AS CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
FROM T_CLIENT LEFT JOIN T_AVOIR_FACTURE on T_CLIENT.CL_ID =
T_AVOIR_FACTURE.CL_ID
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE %{pClientRS}%
AND T_AVOIR_FACTURE.AF_DATE BETWEEN {pDateDeb} AND {pDateFin}
AND (T_AVOIR_FACTURE.CL_ID IS NOT NULL)
GROUP BY CL_ID, CL_RAISON_SOCIALE

ORDER BY CL_RAISON_SOCIALE

celle ci mais 3 sec pour remonter 3584 enreg contre plus de 20 sec pour
1792 enreg (NB : le test de la raison sociale est contient dans les 2
cas et non commence)

--
Cordialement JeAn-PhI
Avatar
Emprin, Frederic
Comme je le disais precedement cela depend FORTEMENT du moteur
car c'est lui qui interprete la requete

bon dev
@+

"JeAn-PhI" a écrit dans le message de news:

Emprin, Frederic a couché sur son écran :
Bonjour,

bon voici un exemple mais a condition que le moteur de base comme oracle
ou sqlserveur, mysql
accepte les sous requetes. averifier mais par experience je dirait
qu'entre l'union et cette requete le temps est presque identique.
l'avantage est d'avoir le resultat sur 1 seule ligne pour chaque client



[CUT]
après correction et modif pour adapter au moteur HF voici ce que ca donne
:

SELECT TABLE1.CL_ID as CL_ID,
TABLE1.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(TABLE1.TotalFacture) AS TotalFacture,
SUM(TABLE2.TotalAvoir) AS TotalAvoir

FROM (SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS TotalFacture
FROM T_CLIENT LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
AND (T_FACTURE.CL_ID is not null)
GROUP BY CL_ID,CL_RAISON_SOCIALE) AS TABLE1

LEFT JOIN

(SELECT T_CLIENT.CL_ID as CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS TotalAvoir
FROM T_CLIENT LEFT JOIN T_AVOIR_FACTURE ON T_AVOIR_FACTURE.CL_ID =
T_CLIENT.CL_ID
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
AND (T_AVOIR_FACTURE.CL_ID is not null)
GROUP BY CL_ID,CL_RAISON_SOCIALE) AS TABLE2

ON TABLE1.CL_ID = TABLE2.CL_ID

GROUP BY CL_ID,CL_RAISON_SOCIALE
ORDER BY CL_RAISON_SOCIALE

j'ai mis le test de la date dans la close WHERE car dans le LEFT JOIN cela
ne fonctionne pas dans ce cas

remarque :
le test de la date dans la close WHERE est plus rapide que dans le LEFT
JOIN

remarque 2 :
SELECT T_CLIENT.CL_ID AS CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_CLIENT LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE %{pClientRS}%
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
AND (T_FACTURE.CL_ID IS NOT NULL)
GROUP BY CL_ID, CL_RAISON_SOCIALE

UNION ALL

SELECT T_CLIENT.CL_ID AS CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
FROM T_CLIENT LEFT JOIN T_AVOIR_FACTURE on T_CLIENT.CL_ID =
T_AVOIR_FACTURE.CL_ID
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE %{pClientRS}%
AND T_AVOIR_FACTURE.AF_DATE BETWEEN {pDateDeb} AND {pDateFin}
AND (T_AVOIR_FACTURE.CL_ID IS NOT NULL)
GROUP BY CL_ID, CL_RAISON_SOCIALE

ORDER BY CL_RAISON_SOCIALE

celle ci mais 3 sec pour remonter 3584 enreg contre plus de 20 sec pour
1792 enreg (NB : le test de la raison sociale est contient dans les 2 cas
et non commence)

--
Cordialement JeAn-PhI




Avatar
JeAn-PhI
bonjour

je reviens avec une autre requête dont je n'arrive pas à formulé
voici le modèle des data

t_client(0,n)->(1,1)t_facture(0,1)->(1,1)t_paiement_facture

je voudrais recupérer la liste des clients ayant une ou des factures
payées selon une période donnée

avec

t_client : cli_id, cli_raison_sociale
t_facture : fa_id, fa_date, cli_id
t_paiement_facture : pa_id, fa_id

merci

--
Cordialement JeAn-PhI
1 2 3