diff --git a/inc-compilo-api.php3 b/inc-compilo-api.php3
index 5180c14ffca997c4a3d08be17ce349403c3e9518..f50d573cf87c24b9e40ac9b12006f8e16ff3b60b 100644
--- a/inc-compilo-api.php3
+++ b/inc-compilo-api.php3
@@ -57,6 +57,7 @@ class Boucle {
 	var $select = array();
 	var $from = array();
 	var $where = array();
+	var $join = array();
 	var $having = 0;
 	var $limit;
 	var $group = array();
diff --git a/inc-compilo.php3 b/inc-compilo.php3
index 7273ec8c0d5653e26bd90d1dad82261058f4dc5d..4a3e2fe2aafbb8dbb0165ca0531b2c2abc82bd73 100644
--- a/inc-compilo.php3
+++ b/inc-compilo.php3
@@ -225,13 +225,11 @@ function calculer_boucle($id_boucle, &$boucles) {
 		(!$boucle->select ? 1 :
 		 join("\",\n\t\t\"", $boucle->select)) .
 		'"), # SELECT
-		' . calculer_from($boucle->from) .
+		' . calculer_from($boucle) .
 		', # FROM
-		array(' .
-		(!$boucle->where ? '' : ( '"' . join('",
-		"', $boucle->where) . '"')) .
-		"), # WHERE
-		" . (!$boucle->group ? "''" : 
+		' . calculer_where($boucle) .
+		', # WHERE
+		' . (!$boucle->group ? "''" : 
 		     ('"' . join(", ", $boucle->group)) . '"') .
 		", # GROUP
 		array(" .
@@ -275,13 +273,22 @@ function calculer_boucle($id_boucle, &$boucles) {
     "\n	return \$t0;";
 }
 
-function calculer_from($t)
+function calculer_from(&$boucle)
 {
   $res = "";
-  foreach($t as $k => $v) $res .= "\", \"$v AS $k";
+  foreach($boucle->from as $k => $v) $res .= "\", \"$v AS $k";
   return 'array(' . substr($res,3) . '")';
 }
 
+function calculer_where(&$boucle)
+{
+  $w = array_merge($boucle->where, $boucle->join);
+  return 'array(' .
+    (!$w ? '' : ( '"' . join('", 
+		"', $w) . '"')) .
+    ")";
+}
+
 //
 // fonction traitant les criteres {1,n} (analyses dans inc-criteres)
 //
diff --git a/inc-criteres.php3 b/inc-criteres.php3
index b6b06015ba2a33bd7136aa1a8874ed0d420ab1d7..2a428dd7e0d4af27adfd35e82d348229e9870596 100644
--- a/inc-criteres.php3
+++ b/inc-criteres.php3
@@ -544,9 +544,11 @@ function calculer_jointure(&$boucle, $depart, $arrivee)
   $res = calculer_chaine_jointures($boucle, $depart, $arrivee);
   if (!$res) return "";
   $n = "";
+  $i = count($res);
   foreach($res as $r) {
     list($d, $a, $j) = $r;
-    $n = calculer_critere_externe($boucle, ($n ? "L$n" : $d), $a, $j);
+    $i--;
+    $n = calculer_critere_externe($boucle, ($n ? "L$n" : $d), $a, $j, $i);
   }
   return $n;
 }
@@ -571,7 +573,6 @@ function calculer_chaine_jointures(&$boucle, $depart, $arrivee, $vu=array())
 	      $new[] = $v;
 	      $r = calculer_chaine_jointures($boucle, array($table, $join), $arrivee, $new);
 	      if ($r)
-		
 		{
 		  array_unshift($r, array($dnom, $table, $k));
 		  return $r;
@@ -630,14 +631,19 @@ function trouver_champ_exterieur($cle, $joints, &$boucle)
 }
 
 // traitement des relations externes par DES jointures.
+// mais ne pas dupliquer les jointures intermediaires
 
-function calculer_critere_externe(&$boucle, $id_table, $lien, $join) {
+function calculer_critere_externe(&$boucle, $id_table, $lien, $join, $suite) {
 	static $num;
 	$id_field = $id_table . '.' . $join; 
+	if ($suite)
+	  foreach ($boucle->join as $v) {
+	    if (ereg("^$id_field=L([0-9]+)\.$join$",$v, $r)) return $r[1];
+	  }
 	$num++;
 	$boucle->lien = true;
 	$boucle->from["L$num"] = $lien;
-	$boucle->where[] = "$id_field=L$num." . $join;
+	$boucle->join[] = "$id_field=L$num." . $join;
 	if (!in_array($id_field, $boucle->group))
 	  $boucle->group[] = $id_field;
 	// postgres exige que le champ pour GROUP soit dans le SELECT