Bonjour,
Est-ce que quelqu'un trouve une explication pour les difficultés avec la
requête N° 3 qui est en principe identique à la 4 mais renvoie n'importe
quoi? La base est toujours le FROM et WHERE du No 1, le reste
rajouté suivant les filtres en place. Donc, la seule chose
différente entre les 4 versions c'est le WHERE à partir de la 2e ligne.
J'aimerais bien comprendre ce problème. Merci de vos lumières.
Mat
1) OK, retourne 240 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND ContractDetail.Balance <> 0
2) OK, retourne 1 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND Contract.Date >= '20030101'
AND Contract.Date <= '20031231'
AND ContractDetail.Balance <> 0
3) Retourne > 93000 enregistrements (le fichier ContractDetail a env 4000
enreg, donc les lignes sont multipliées pour une raison X):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND ContractDetail.Balance <> 0
4) OK, retourne 160 enregs (correspond à ce que je voulais obtenir avec 3):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContract IN (SELECT IDContract FROM Contract C WHERE
IDContractType IN (2,4) )
AND ContractDetail.Balance <> 0
Bonjour,
Est-ce que quelqu'un trouve une explication pour les difficultés avec la
requête N° 3 qui est en principe identique à la 4 mais renvoie n'importe
quoi? La base est toujours le FROM et WHERE du No 1, le reste
rajouté suivant les filtres en place. Donc, la seule chose
différente entre les 4 versions c'est le WHERE à partir de la 2e ligne.
J'aimerais bien comprendre ce problème. Merci de vos lumières.
Mat
1) OK, retourne 240 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND ContractDetail.Balance <> 0
2) OK, retourne 1 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND Contract.Date >= '20030101'
AND Contract.Date <= '20031231'
AND ContractDetail.Balance <> 0
3) Retourne > 93000 enregistrements (le fichier ContractDetail a env 4000
enreg, donc les lignes sont multipliées pour une raison X):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND ContractDetail.Balance <> 0
4) OK, retourne 160 enregs (correspond à ce que je voulais obtenir avec 3):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContract IN (SELECT IDContract FROM Contract C WHERE
IDContractType IN (2,4) )
AND ContractDetail.Balance <> 0
Bonjour,
Est-ce que quelqu'un trouve une explication pour les difficultés avec la
requête N° 3 qui est en principe identique à la 4 mais renvoie n'importe
quoi? La base est toujours le FROM et WHERE du No 1, le reste
rajouté suivant les filtres en place. Donc, la seule chose
différente entre les 4 versions c'est le WHERE à partir de la 2e ligne.
J'aimerais bien comprendre ce problème. Merci de vos lumières.
Mat
1) OK, retourne 240 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND ContractDetail.Balance <> 0
2) OK, retourne 1 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND Contract.Date >= '20030101'
AND Contract.Date <= '20031231'
AND ContractDetail.Balance <> 0
3) Retourne > 93000 enregistrements (le fichier ContractDetail a env 4000
enreg, donc les lignes sont multipliées pour une raison X):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND ContractDetail.Balance <> 0
4) OK, retourne 160 enregs (correspond à ce que je voulais obtenir avec 3):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract > ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct > Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContract IN (SELECT IDContract FROM Contract C WHERE
IDContractType IN (2,4) )
AND ContractDetail.Balance <> 0
1) OK, retourne 240 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND ContractDetail.Balance <> 0
1ere question Pourquoi un left join entre contractDetail et contract ?
Il me semble difficile pour un contractdetail d'exister sans un Contract.
Meme chose entre ContractDetail et Product.
Attention à la jointure gauche qui plombe les performances d'une requête.
pour moi ce serait plutôt (en mySQL car je ne pratique pas le HF mais
j'espère que ce n'est pas différent)
FROM (((ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract) INNER JOIN Product
on ContractDetail.IDProduct = Product.IDProduct) LEFT JOIN Adress ON
Contract.IDCustSupp = Address.IDAddress)
WHERE ...
2) OK, retourne 1 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND Contract.Date >= '20030101'
AND Contract.Date <= '20031231'
AND ContractDetail.Balance <> 0
Si tu nous changes les Where, on veut bien te croire que cela ne donne
pas le meme nbre d'enregs?
3) Retourne > 93000 enregistrements (le fichier ContractDetail a env
4000 enreg, donc les lignes sont multipliées pour une raison X):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND ContractDetail.Balance <> 0
Parce que tu utilises des jointures gauche alors qu'il faut utiliser des
équijointures
4) OK, retourne 160 enregs (correspond à ce que je voulais obtenir
avec 3):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContract IN (SELECT IDContract FROM Contract C WHERE
IDContractType IN (2,4) )
AND ContractDetail.Balance <> 0
A mon avis soit tu as un modèle spec ;-) soit tu n'as pas bien compris
la notion de left join.
ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les
détail contrats et leur en-tête contrat (le plus logique non ?)
Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract =
ContractDetail.IDContract : je prends tous les contrats meme ceux qui
n'ont pas de détails (pourquoi pas ?)
ContractDetail LEFT OUTER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les
détails contrats meme s'il n'ont pas d'en tete (bizarre ?)
Volià, j'espère que cela pourra t'aider.
1) OK, retourne 240 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND ContractDetail.Balance <> 0
1ere question Pourquoi un left join entre contractDetail et contract ?
Il me semble difficile pour un contractdetail d'exister sans un Contract.
Meme chose entre ContractDetail et Product.
Attention à la jointure gauche qui plombe les performances d'une requête.
pour moi ce serait plutôt (en mySQL car je ne pratique pas le HF mais
j'espère que ce n'est pas différent)
FROM (((ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract) INNER JOIN Product
on ContractDetail.IDProduct = Product.IDProduct) LEFT JOIN Adress ON
Contract.IDCustSupp = Address.IDAddress)
WHERE ...
2) OK, retourne 1 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND Contract.Date >= '20030101'
AND Contract.Date <= '20031231'
AND ContractDetail.Balance <> 0
Si tu nous changes les Where, on veut bien te croire que cela ne donne
pas le meme nbre d'enregs?
3) Retourne > 93000 enregistrements (le fichier ContractDetail a env
4000 enreg, donc les lignes sont multipliées pour une raison X):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND ContractDetail.Balance <> 0
Parce que tu utilises des jointures gauche alors qu'il faut utiliser des
équijointures
4) OK, retourne 160 enregs (correspond à ce que je voulais obtenir
avec 3):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContract IN (SELECT IDContract FROM Contract C WHERE
IDContractType IN (2,4) )
AND ContractDetail.Balance <> 0
A mon avis soit tu as un modèle spec ;-) soit tu n'as pas bien compris
la notion de left join.
ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les
détail contrats et leur en-tête contrat (le plus logique non ?)
Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract =
ContractDetail.IDContract : je prends tous les contrats meme ceux qui
n'ont pas de détails (pourquoi pas ?)
ContractDetail LEFT OUTER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les
détails contrats meme s'il n'ont pas d'en tete (bizarre ?)
Volià, j'espère que cela pourra t'aider.
1) OK, retourne 240 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND ContractDetail.Balance <> 0
1ere question Pourquoi un left join entre contractDetail et contract ?
Il me semble difficile pour un contractdetail d'exister sans un Contract.
Meme chose entre ContractDetail et Product.
Attention à la jointure gauche qui plombe les performances d'une requête.
pour moi ce serait plutôt (en mySQL car je ne pratique pas le HF mais
j'espère que ce n'est pas différent)
FROM (((ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract) INNER JOIN Product
on ContractDetail.IDProduct = Product.IDProduct) LEFT JOIN Adress ON
Contract.IDCustSupp = Address.IDAddress)
WHERE ...
2) OK, retourne 1 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND Contract.Date >= '20030101'
AND Contract.Date <= '20031231'
AND ContractDetail.Balance <> 0
Si tu nous changes les Where, on veut bien te croire que cela ne donne
pas le meme nbre d'enregs?
3) Retourne > 93000 enregistrements (le fichier ContractDetail a env
4000 enreg, donc les lignes sont multipliées pour une raison X):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND ContractDetail.Balance <> 0
Parce que tu utilises des jointures gauche alors qu'il faut utiliser des
équijointures
4) OK, retourne 160 enregs (correspond à ce que je voulais obtenir
avec 3):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContract IN (SELECT IDContract FROM Contract C WHERE
IDContractType IN (2,4) )
AND ContractDetail.Balance <> 0
A mon avis soit tu as un modèle spec ;-) soit tu n'as pas bien compris
la notion de left join.
ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les
détail contrats et leur en-tête contrat (le plus logique non ?)
Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract =
ContractDetail.IDContract : je prends tous les contrats meme ceux qui
n'ont pas de détails (pourquoi pas ?)
ContractDetail LEFT OUTER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les
détails contrats meme s'il n'ont pas d'en tete (bizarre ?)
Volià, j'espère que cela pourra t'aider.
Volià, j'espère que cela pourra t'aider.
Volià, j'espère que cela pourra t'aider.
Volià, j'espère que cela pourra t'aider.
Roumegou wrote:1) OK, retourne 240 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND ContractDetail.Balance <> 0
1ere question Pourquoi un left join entre contractDetail et contract ?
Il me semble difficile pour un contractdetail d'exister sans un Contract.
Meme chose entre ContractDetail et Product.
Attention à la jointure gauche qui plombe les performances d'une requête.
Le left outer join est entre Contract et ContractDetail, ne pas vice-versa.
Je pense LEFT se réfère au fichier qui est a gauche (de LEFT), ou je me
trompe? Le but de cette jointure est que je veux récupérer des entêtes sans
détails.
Je suis d'accord que le code n'est peut-être pas très nette. Dans mon
expérience, de temps en temps un serveur se bloque ce qui résulte dans des
enregistrements incomplets. Je veux que la requête me retourne toutes
commandes, même sans code client, enregistrement détail et code produit.
pour moi ce serait plutôt (en mySQL car je ne pratique pas le HF mais
j'espère que ce n'est pas différent)
FROM (((ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract) INNER JOIN Product
on ContractDetail.IDProduct = Product.IDProduct) LEFT JOIN Adress ON
Contract.IDCustSupp = Address.IDAddress)
WHERE ...
Il me semble que celle-ci ne me retourne pas les entêtes sans détails...2) OK, retourne 1 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND Contract.Date >= '20030101'
AND Contract.Date <= '20031231'
AND ContractDetail.Balance <> 0
Si tu nous changes les Where, on veut bien te croire que cela ne donne pas
le meme nbre d'enregs?
J'ai spécifié que mon problème est le N° 3 par rapport au 4. Cette exemple N°
2 montre que le IN (même que N° 3) fonctionne dans ce format, lorsqu'il y a
une autre condition.3) Retourne > 93000 enregistrements (le fichier ContractDetail a env 4000
enreg, donc les lignes sont multipliées pour une raison X):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND ContractDetail.Balance <> 0
Parce que tu utilises des jointures gauche alors qu'il faut utiliser des
équijointures
Je regrette, je ne comprends pas la différence au N° 2.4) OK, retourne 160 enregs (correspond à ce que je voulais obtenir avec
3):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContract IN (SELECT IDContract FROM Contract C WHERE
IDContractType IN (2,4) )
AND ContractDetail.Balance <> 0
A mon avis soit tu as un modèle spec ;-) soit tu n'as pas bien compris la
notion de left join.
ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les détail
contrats et leur en-tête contrat (le plus logique non ?)
commentaire sous 1.Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract =
ContractDetail.IDContract : je prends tous les contrats meme ceux qui n'ont
pas de détails (pourquoi pas ?)
commentaires sous 1.
ContractDetail LEFT OUTER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les détails
contrats meme s'il n'ont pas d'en tete (bizarre ?)
Je ne trouve pas ceci dans mon code. Le seul ContractDetail LEFT OUTER JOIN
que je vois est celui avec Product (l'ID se trouve dans ContractDetail).Volià, j'espère que cela pourra t'aider.
Merci beaucoup pour ton aide. Je pense j'y arrivera si tu peux m'expliquer
pourquoi les mêmes jointures fonctionnent dans l'exemple 2 et 4, mais pas
dans le No 3. Ne nombre d'enregistrements est uniquement en cause entre les
Nos 3 et 4 qui devraient, à mon avis, donner le même résultat.
Mat
Roumegou wrote:
1) OK, retourne 240 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND ContractDetail.Balance <> 0
1ere question Pourquoi un left join entre contractDetail et contract ?
Il me semble difficile pour un contractdetail d'exister sans un Contract.
Meme chose entre ContractDetail et Product.
Attention à la jointure gauche qui plombe les performances d'une requête.
Le left outer join est entre Contract et ContractDetail, ne pas vice-versa.
Je pense LEFT se réfère au fichier qui est a gauche (de LEFT), ou je me
trompe? Le but de cette jointure est que je veux récupérer des entêtes sans
détails.
Je suis d'accord que le code n'est peut-être pas très nette. Dans mon
expérience, de temps en temps un serveur se bloque ce qui résulte dans des
enregistrements incomplets. Je veux que la requête me retourne toutes
commandes, même sans code client, enregistrement détail et code produit.
pour moi ce serait plutôt (en mySQL car je ne pratique pas le HF mais
j'espère que ce n'est pas différent)
FROM (((ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract) INNER JOIN Product
on ContractDetail.IDProduct = Product.IDProduct) LEFT JOIN Adress ON
Contract.IDCustSupp = Address.IDAddress)
WHERE ...
Il me semble que celle-ci ne me retourne pas les entêtes sans détails...
2) OK, retourne 1 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND Contract.Date >= '20030101'
AND Contract.Date <= '20031231'
AND ContractDetail.Balance <> 0
Si tu nous changes les Where, on veut bien te croire que cela ne donne pas
le meme nbre d'enregs?
J'ai spécifié que mon problème est le N° 3 par rapport au 4. Cette exemple N°
2 montre que le IN (même que N° 3) fonctionne dans ce format, lorsqu'il y a
une autre condition.
3) Retourne > 93000 enregistrements (le fichier ContractDetail a env 4000
enreg, donc les lignes sont multipliées pour une raison X):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND ContractDetail.Balance <> 0
Parce que tu utilises des jointures gauche alors qu'il faut utiliser des
équijointures
Je regrette, je ne comprends pas la différence au N° 2.
4) OK, retourne 160 enregs (correspond à ce que je voulais obtenir avec
3):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContract IN (SELECT IDContract FROM Contract C WHERE
IDContractType IN (2,4) )
AND ContractDetail.Balance <> 0
A mon avis soit tu as un modèle spec ;-) soit tu n'as pas bien compris la
notion de left join.
ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les détail
contrats et leur en-tête contrat (le plus logique non ?)
commentaire sous 1.
Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract =
ContractDetail.IDContract : je prends tous les contrats meme ceux qui n'ont
pas de détails (pourquoi pas ?)
commentaires sous 1.
ContractDetail LEFT OUTER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les détails
contrats meme s'il n'ont pas d'en tete (bizarre ?)
Je ne trouve pas ceci dans mon code. Le seul ContractDetail LEFT OUTER JOIN
que je vois est celui avec Product (l'ID se trouve dans ContractDetail).
Volià, j'espère que cela pourra t'aider.
Merci beaucoup pour ton aide. Je pense j'y arrivera si tu peux m'expliquer
pourquoi les mêmes jointures fonctionnent dans l'exemple 2 et 4, mais pas
dans le No 3. Ne nombre d'enregistrements est uniquement en cause entre les
Nos 3 et 4 qui devraient, à mon avis, donner le même résultat.
Mat
Roumegou wrote:1) OK, retourne 240 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND ContractDetail.Balance <> 0
1ere question Pourquoi un left join entre contractDetail et contract ?
Il me semble difficile pour un contractdetail d'exister sans un Contract.
Meme chose entre ContractDetail et Product.
Attention à la jointure gauche qui plombe les performances d'une requête.
Le left outer join est entre Contract et ContractDetail, ne pas vice-versa.
Je pense LEFT se réfère au fichier qui est a gauche (de LEFT), ou je me
trompe? Le but de cette jointure est que je veux récupérer des entêtes sans
détails.
Je suis d'accord que le code n'est peut-être pas très nette. Dans mon
expérience, de temps en temps un serveur se bloque ce qui résulte dans des
enregistrements incomplets. Je veux que la requête me retourne toutes
commandes, même sans code client, enregistrement détail et code produit.
pour moi ce serait plutôt (en mySQL car je ne pratique pas le HF mais
j'espère que ce n'est pas différent)
FROM (((ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract) INNER JOIN Product
on ContractDetail.IDProduct = Product.IDProduct) LEFT JOIN Adress ON
Contract.IDCustSupp = Address.IDAddress)
WHERE ...
Il me semble que celle-ci ne me retourne pas les entêtes sans détails...2) OK, retourne 1 enreg.:
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND Contract.Date >= '20030101'
AND Contract.Date <= '20031231'
AND ContractDetail.Balance <> 0
Si tu nous changes les Where, on veut bien te croire que cela ne donne pas
le meme nbre d'enregs?
J'ai spécifié que mon problème est le N° 3 par rapport au 4. Cette exemple N°
2 montre que le IN (même que N° 3) fonctionne dans ce format, lorsqu'il y a
une autre condition.3) Retourne > 93000 enregistrements (le fichier ContractDetail a env 4000
enreg, donc les lignes sont multipliées pour une raison X):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContractType IN (2,4)
AND ContractDetail.Balance <> 0
Parce que tu utilises des jointures gauche alors qu'il faut utiliser des
équijointures
Je regrette, je ne comprends pas la différence au N° 2.4) OK, retourne 160 enregs (correspond à ce que je voulais obtenir avec
3):
FROM Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract >>> ContractDetail.IDContract,
ContractDetail LEFT OUTER JOIN Product on ContractDetail.IDProduct >>> Product.IDProduct, Contract LEFT OUTER JOIN Address on
Contract.IDCustSupp = Address.IDAddress
WHERE Contract.IDContractType < 8
AND Contract.IDContract IN (SELECT IDContract FROM Contract C WHERE
IDContractType IN (2,4) )
AND ContractDetail.Balance <> 0
A mon avis soit tu as un modèle spec ;-) soit tu n'as pas bien compris la
notion de left join.
ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les détail
contrats et leur en-tête contrat (le plus logique non ?)
commentaire sous 1.Contract LEFT OUTER JOIN ContractDetail on Contract.IDContract =
ContractDetail.IDContract : je prends tous les contrats meme ceux qui n'ont
pas de détails (pourquoi pas ?)
commentaires sous 1.
ContractDetail LEFT OUTER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract : je prends tous les détails
contrats meme s'il n'ont pas d'en tete (bizarre ?)
Je ne trouve pas ceci dans mon code. Le seul ContractDetail LEFT OUTER JOIN
que je vois est celui avec Product (l'ID se trouve dans ContractDetail).Volià, j'espère que cela pourra t'aider.
Merci beaucoup pour ton aide. Je pense j'y arrivera si tu peux m'expliquer
pourquoi les mêmes jointures fonctionnent dans l'exemple 2 et 4, mais pas
dans le No 3. Ne nombre d'enregistrements est uniquement en cause entre les
Nos 3 et 4 qui devraient, à mon avis, donner le même résultat.
Mat
Roumegou wrote:Volià, j'espère que cela pourra t'aider.
En HF, ton code correspond à
"FROM ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract, "+...
"ContractDetail INNER JOIN Product on ContractDetail.IDProduct =
Product.IDProduct, "+...
"Contract LEFT JOIN Address ON Contract.IDCustSupp = Address.IDAddress "+...
"WHERE Contract.IDContractType < 8 "
Elle marche mais ne donne pas les entêtes sans détails.
J'ai oublié de dire que je n'ai jamais réussi d'obtenir le résultat voulu
avec les jointures indiquées. Je pense le problème vient des filtres sur
ContractDetail. Je dépanne avec une requête UNION sans aucun filtre sur
ContractDetail. Ca marche mais n'est probablement pas très efficace.
Roumegou wrote:
Volià, j'espère que cela pourra t'aider.
En HF, ton code correspond à
"FROM ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract, "+...
"ContractDetail INNER JOIN Product on ContractDetail.IDProduct =
Product.IDProduct, "+...
"Contract LEFT JOIN Address ON Contract.IDCustSupp = Address.IDAddress "+...
"WHERE Contract.IDContractType < 8 "
Elle marche mais ne donne pas les entêtes sans détails.
J'ai oublié de dire que je n'ai jamais réussi d'obtenir le résultat voulu
avec les jointures indiquées. Je pense le problème vient des filtres sur
ContractDetail. Je dépanne avec une requête UNION sans aucun filtre sur
ContractDetail. Ca marche mais n'est probablement pas très efficace.
Roumegou wrote:Volià, j'espère que cela pourra t'aider.
En HF, ton code correspond à
"FROM ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract, "+...
"ContractDetail INNER JOIN Product on ContractDetail.IDProduct =
Product.IDProduct, "+...
"Contract LEFT JOIN Address ON Contract.IDCustSupp = Address.IDAddress "+...
"WHERE Contract.IDContractType < 8 "
Elle marche mais ne donne pas les entêtes sans détails.
J'ai oublié de dire que je n'ai jamais réussi d'obtenir le résultat voulu
avec les jointures indiquées. Je pense le problème vient des filtres sur
ContractDetail. Je dépanne avec une requête UNION sans aucun filtre sur
ContractDetail. Ca marche mais n'est probablement pas très efficace.
Oui mais normalement une commande ne peut exister sans détail et une
ligne ne peut exister sans code produit.
Enfin, on fait comme on veut;(et cela dépend de ton analyse) mais par
expérience, des en-têtes vides provoquent des incohérences. Donc dès que
l'on supprime toutes les lignes d'une commande, on supprime
automatiquement l'en tete, ou si l'on valide une commande sans avoir
saisit de détail, on supprime l'en tete.
avec ContractDetail.Balance<>0 ; ce test élimine (pour un sgbd
normalement constitué) tous les contrats sans contractdétail puisque on
ne peut faire de tests sur une valeur null. Ou alors il faudrait
Mais je suis désolé, je n'arrive pas à suivre ta logique.
Oui mais normalement une commande ne peut exister sans détail et une
ligne ne peut exister sans code produit.
Enfin, on fait comme on veut;(et cela dépend de ton analyse) mais par
expérience, des en-têtes vides provoquent des incohérences. Donc dès que
l'on supprime toutes les lignes d'une commande, on supprime
automatiquement l'en tete, ou si l'on valide une commande sans avoir
saisit de détail, on supprime l'en tete.
avec ContractDetail.Balance<>0 ; ce test élimine (pour un sgbd
normalement constitué) tous les contrats sans contractdétail puisque on
ne peut faire de tests sur une valeur null. Ou alors il faudrait
Mais je suis désolé, je n'arrive pas à suivre ta logique.
Oui mais normalement une commande ne peut exister sans détail et une
ligne ne peut exister sans code produit.
Enfin, on fait comme on veut;(et cela dépend de ton analyse) mais par
expérience, des en-têtes vides provoquent des incohérences. Donc dès que
l'on supprime toutes les lignes d'une commande, on supprime
automatiquement l'en tete, ou si l'on valide une commande sans avoir
saisit de détail, on supprime l'en tete.
avec ContractDetail.Balance<>0 ; ce test élimine (pour un sgbd
normalement constitué) tous les contrats sans contractdétail puisque on
ne peut faire de tests sur une valeur null. Ou alors il faudrait
Mais je suis désolé, je n'arrive pas à suivre ta logique.
mat avait écrit le 24/04/2004 :Roumegou wrote:Volià, j'espère que cela pourra t'aider.
En HF, ton code correspond à
"FROM ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract, "+...
"ContractDetail INNER JOIN Product on ContractDetail.IDProduct =
Product.IDProduct, "+...
"Contract LEFT JOIN Address ON Contract.IDCustSupp = Address.IDAddress
"+...
"WHERE Contract.IDContractType < 8 "
Elle marche mais ne donne pas les entêtes sans détails.
cf mon post précédent.
Si tu fais des tests sur des zones de contractdetail (balance par ex),
il ne seront pas satisfaits pour les tuples sans contractdetail (valeur
null).
Attention, peut être cela se passe comme cela avec HF mais si tu passes
sur Oracle par ex, cela ne marchera pas. Autant prendre tout de suite
les bonnes habitudes.
mat avait écrit le 24/04/2004 :
Roumegou wrote:
Volià, j'espère que cela pourra t'aider.
En HF, ton code correspond à
"FROM ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract, "+...
"ContractDetail INNER JOIN Product on ContractDetail.IDProduct =
Product.IDProduct, "+...
"Contract LEFT JOIN Address ON Contract.IDCustSupp = Address.IDAddress
"+...
"WHERE Contract.IDContractType < 8 "
Elle marche mais ne donne pas les entêtes sans détails.
cf mon post précédent.
Si tu fais des tests sur des zones de contractdetail (balance par ex),
il ne seront pas satisfaits pour les tuples sans contractdetail (valeur
null).
Attention, peut être cela se passe comme cela avec HF mais si tu passes
sur Oracle par ex, cela ne marchera pas. Autant prendre tout de suite
les bonnes habitudes.
mat avait écrit le 24/04/2004 :Roumegou wrote:Volià, j'espère que cela pourra t'aider.
En HF, ton code correspond à
"FROM ContractDetail INNER JOIN Contract on
ContractDetail.IDContract=Contract.IDContract, "+...
"ContractDetail INNER JOIN Product on ContractDetail.IDProduct =
Product.IDProduct, "+...
"Contract LEFT JOIN Address ON Contract.IDCustSupp = Address.IDAddress
"+...
"WHERE Contract.IDContractType < 8 "
Elle marche mais ne donne pas les entêtes sans détails.
cf mon post précédent.
Si tu fais des tests sur des zones de contractdetail (balance par ex),
il ne seront pas satisfaits pour les tuples sans contractdetail (valeur
null).
Attention, peut être cela se passe comme cela avec HF mais si tu passes
sur Oracle par ex, cela ne marchera pas. Autant prendre tout de suite
les bonnes habitudes.
Bonsoir Eric,
J'aimerais obtenir:
1) Les entêtes (Contract)
- avec ou sans détails (ContractDetail)
- avec ou sans ID client (liaison vers Address)
2) Les détails relatifs aux entêtes trouvés
- avec ou sans ID Produit (liaison vers Product)
3) Le nom du client, lorsque l'ID est disponible, sinon blanc
4) La désignation du produit, lorsque l'ID est disponible, sinon blanc
Est-elle vraiment si tordue ma logique, ou peut-être mon français trop
rudimentaire? De toute façon, encore merci.
Bonsoir Eric,
J'aimerais obtenir:
1) Les entêtes (Contract)
- avec ou sans détails (ContractDetail)
- avec ou sans ID client (liaison vers Address)
2) Les détails relatifs aux entêtes trouvés
- avec ou sans ID Produit (liaison vers Product)
3) Le nom du client, lorsque l'ID est disponible, sinon blanc
4) La désignation du produit, lorsque l'ID est disponible, sinon blanc
Est-elle vraiment si tordue ma logique, ou peut-être mon français trop
rudimentaire? De toute façon, encore merci.
Bonsoir Eric,
J'aimerais obtenir:
1) Les entêtes (Contract)
- avec ou sans détails (ContractDetail)
- avec ou sans ID client (liaison vers Address)
2) Les détails relatifs aux entêtes trouvés
- avec ou sans ID Produit (liaison vers Product)
3) Le nom du client, lorsque l'ID est disponible, sinon blanc
4) La désignation du produit, lorsque l'ID est disponible, sinon blanc
Est-elle vraiment si tordue ma logique, ou peut-être mon français trop
rudimentaire? De toute façon, encore merci.
mat a formulé ce dimanche :Bonsoir Eric,
[CUT]J'aimerais obtenir:
1) Les entêtes (Contract)
- avec ou sans détails (ContractDetail)
- avec ou sans ID client (liaison vers Address)
2) Les détails relatifs aux entêtes trouvés
- avec ou sans ID Produit (liaison vers Product)
3) Le nom du client, lorsque l'ID est disponible, sinon blanc
4) La désignation du produit, lorsque l'ID est disponible, sinon blanc
Okay pour ce contexte particulier (élément pertubé risque de
désynchonisation).
Dans ce cas, je gèrerais cela par deux requetes.
Je pars des contracts avec adress en left join.
Pour chaque contrat; je lance une requete sur contractdetail avec
produit en left join. Là pas de surprises.
Mais franchement, que tu utilises ces deux requetes ou les left join,
les performances ne seront pas au rdv.?
Pour ma part, (mais encore une fois c'est toi qui connais mieux ton
contexte) avoir des commandes sans détail et des détails sans produits
ne m'interesse pas. Je préfèrerai les ignorer par des inner join, quitte
à faire le ménage de temps en temps avec une requete de type DELETE
CONTRACT WHERE CONTRACTID NOT IN (SELECT DISTINCT CONTRACTID FROM
CONTRACTDETAIL).
Autre chose importante : Le contrôle de validation
Je ne vais pas critiquer HF (on vas encore me reprocher mon ostracisme
;-) ) mais si tu travailles avec un SGBD qui gère les transactions, tu
peux éviter les dysfonctionnements dus aux arrêts intempestifs avec les
commit, rollback)
mat a formulé ce dimanche :
Bonsoir Eric,
[CUT]
J'aimerais obtenir:
1) Les entêtes (Contract)
- avec ou sans détails (ContractDetail)
- avec ou sans ID client (liaison vers Address)
2) Les détails relatifs aux entêtes trouvés
- avec ou sans ID Produit (liaison vers Product)
3) Le nom du client, lorsque l'ID est disponible, sinon blanc
4) La désignation du produit, lorsque l'ID est disponible, sinon blanc
Okay pour ce contexte particulier (élément pertubé risque de
désynchonisation).
Dans ce cas, je gèrerais cela par deux requetes.
Je pars des contracts avec adress en left join.
Pour chaque contrat; je lance une requete sur contractdetail avec
produit en left join. Là pas de surprises.
Mais franchement, que tu utilises ces deux requetes ou les left join,
les performances ne seront pas au rdv.?
Pour ma part, (mais encore une fois c'est toi qui connais mieux ton
contexte) avoir des commandes sans détail et des détails sans produits
ne m'interesse pas. Je préfèrerai les ignorer par des inner join, quitte
à faire le ménage de temps en temps avec une requete de type DELETE
CONTRACT WHERE CONTRACTID NOT IN (SELECT DISTINCT CONTRACTID FROM
CONTRACTDETAIL).
Autre chose importante : Le contrôle de validation
Je ne vais pas critiquer HF (on vas encore me reprocher mon ostracisme
;-) ) mais si tu travailles avec un SGBD qui gère les transactions, tu
peux éviter les dysfonctionnements dus aux arrêts intempestifs avec les
commit, rollback)
mat a formulé ce dimanche :Bonsoir Eric,
[CUT]J'aimerais obtenir:
1) Les entêtes (Contract)
- avec ou sans détails (ContractDetail)
- avec ou sans ID client (liaison vers Address)
2) Les détails relatifs aux entêtes trouvés
- avec ou sans ID Produit (liaison vers Product)
3) Le nom du client, lorsque l'ID est disponible, sinon blanc
4) La désignation du produit, lorsque l'ID est disponible, sinon blanc
Okay pour ce contexte particulier (élément pertubé risque de
désynchonisation).
Dans ce cas, je gèrerais cela par deux requetes.
Je pars des contracts avec adress en left join.
Pour chaque contrat; je lance une requete sur contractdetail avec
produit en left join. Là pas de surprises.
Mais franchement, que tu utilises ces deux requetes ou les left join,
les performances ne seront pas au rdv.?
Pour ma part, (mais encore une fois c'est toi qui connais mieux ton
contexte) avoir des commandes sans détail et des détails sans produits
ne m'interesse pas. Je préfèrerai les ignorer par des inner join, quitte
à faire le ménage de temps en temps avec une requete de type DELETE
CONTRACT WHERE CONTRACTID NOT IN (SELECT DISTINCT CONTRACTID FROM
CONTRACTDETAIL).
Autre chose importante : Le contrôle de validation
Je ne vais pas critiquer HF (on vas encore me reprocher mon ostracisme
;-) ) mais si tu travailles avec un SGBD qui gère les transactions, tu
peux éviter les dysfonctionnements dus aux arrêts intempestifs avec les
commit, rollback)