cedric@yterium.com a écrit :
Author: cedric@yterium.com
Date: Tue Apr 17 13:09:56 2007
New Revision: 11358Log:
"le commit precedent etait errone
ET par defaut sur {filtre}, parametrable dans le squellete par {filtre ET} ou {filtre OU} ou {filtre #ENV{truc}} avec #ENV{truc} valant ET ou OU
pour toute autre valeur que OU c'est ET qui est applique"
Hello !
Bien vu de compter les résultats et de faire une sous-sélection par un HAVING res=x : excellent !
J'ai testé sur une table de 3 champs (2 groupes de mots-clés unique + 1 groupe de mots-clés à sélection multiple) et uniquement avec le filtre ET.
Le principe est bon mais le total $res exigé ne correspond pas à ce qui est obtenu par la requête.
Expérimentalement ça marche, si pour chaque critère du formulaire on ne fait non pas un $res++ mais un $res+=3 ! Y compris pour les tableaux (choix multiples) mais sans prendre en compte le nombre d'éléments (\$res+=3 au lieu de \$res += count(\$r)). [Voir exemple requêtes ci-après]
Probablement un problème de regroupement dans la requête.. En regardant un peu plus dans la requête générée, il semblerait que le problème vienne dans la répétition de l'utilisation de la table spip_forms_donnees_champs (une fois en tant que 'dc' et une seconde en tant que 'donnees_champs').
En supprimant les redondances (dc + donnees_champs => dc) cela permet de comptabiliser +1 par critère au lieu de +3 ! [Ne me demandez par pourquoi !]
Ainsi cela fonctionne en remplaçant la requête :
SELECT forms_donnees.id_form, forms_donnees.id_donnee, COUNT(forms_donnees.id_donnee) AS res, donnees_champs.valeur AS id_mot
FROM `test`.spip_forms_donnees AS `forms_donnees`,
`test`.spip_forms_donnees_champs AS `dc`,
`test`.spip_forms_donnees_champs AS `donnees_champs`,
`test`.spip_forms_champs AS `champs`
WHERE (forms_donnees.id_form = '3')
AND (forms_donnees.confirmation = "valide")
AND (forms_donnees.statut = "publie")
AND ((dc.champ='mot_1' AND dc.valeur='62') OR (dc.champ='mot_3' AND dc.valeur IN ('5','31')))
AND (dc.id_donnee = forms_donnees.id_donnee)
AND (forms_donnees.id_form = champs.id_form)
AND (champs.type = "mot")
AND (donnees_champs.champ = champs.champ)
AND (donnees_champs.id_donnee = forms_donnees.id_donnee)
GROUP BY forms_donnees.id_donnee
HAVING res=6
ORDER BY forms_donnees.rang
par celle-ci :
SELECT forms_donnees.id_form, forms_donnees.id_donnee, COUNT(forms_donnees.id_donnee) AS res, dc.valeur AS id_mot
FROM `test`.spip_forms_donnees AS `forms_donnees`,
`test`.spip_forms_donnees_champs AS `dc`,
`test`.spip_forms_champs AS `champs`
WHERE (forms_donnees.id_form = '3')
AND (forms_donnees.confirmation = "valide")
AND (forms_donnees.statut = "publie")
AND ((dc.champ='mot_1' AND dc.valeur='62') OR (dc.champ='mot_3' AND dc.valeur IN ('5','31')))
AND (dc.id_donnee = forms_donnees.id_donnee)
AND (forms_donnees.id_form = champs.id_form)
AND (champs.type = "mot")
AND (dc.champ = champs.champ)
AND (dc.id_donnee = forms_donnees.id_donnee)
GROUP BY forms_donnees.id_donnee
HAVING res=2
ORDER BY forms_donnees.rang
Cédric, je ne maîtrise pas suffisamment la boucle_FORMS_DONNEES_dist pour faire un commit sans risquer d'introduire des effets de bords... ![]()
Enfin, il y a un petit problème dans la récupération de la valeur pour les champs multiples non renseignés (on se retrouve avec &mot_3%5B%5D= au lieu de &mot_3= dans l'url).
Amicalement,
Philippe
exemple de requêtes générées par la recherche :
SELECT forms_donnees.id_form, forms_donnees.id_donnee, COUNT(forms_donnees.id_donnee) AS res, donnees_champs.valeur AS id_mot
FROM `test`.spip_forms_donnees AS `forms_donnees`, `test`.spip_forms_donnees_champs AS `dc`, `test`.spip_forms_donnees_champs AS `donnees_champs`, `test`.spip_forms_champs AS `champs`
WHERE (forms_donnees.id_form = '3')
AND (forms_donnees.confirmation = "valide")
AND (forms_donnees.statut = "publie")
AND ((dc.champ='mot_1' AND dc.valeur='67') OR (dc.champ='mot_2' AND dc.valeur='73') OR (dc.champ='mot_3' AND dc.valeur IN ('8')))
AND (dc.id_donnee = forms_donnees.id_donnee)
AND (forms_donnees.id_form = champs.id_form)
AND (champs.type = "mot")
AND (donnees_champs.champ = champs.champ)
AND (donnees_champs.id_donnee = forms_donnees.id_donnee)
GROUP BY forms_donnees.id_donnee, forms_donnees.id_donnee
HAVING res=3
ORDER BY forms_donnees.rang
=> donne les bons résultats avec HAVING res=9 !!
SELECT forms_donnees.id_form, forms_donnees.id_donnee, COUNT(forms_donnees.id_donnee) AS res, donnees_champs.valeur AS id_mot
FROM `test`.spip_forms_donnees AS `forms_donnees`, `test`.spip_forms_donnees_champs AS `dc`, `test`.spip_forms_donnees_champs AS `donnees_champs`, `test`.spip_forms_champs AS `champs`
WHERE (forms_donnees.id_form = '3')
AND (forms_donnees.confirmation = "valide")
AND (forms_donnees.statut = "publie")
AND ((dc.champ='mot_1' AND dc.valeur='67') OR (dc.champ='mot_2' AND dc.valeur='73'))
AND (dc.id_donnee = forms_donnees.id_donnee)
AND (forms_donnees.id_form = champs.id_form)
AND (champs.type = "mot")
AND (donnees_champs.champ = champs.champ)
AND (donnees_champs.id_donnee = forms_donnees.id_donnee)
GROUP BY forms_donnees.id_donnee, forms_donnees.id_donnee
HAVING res=2
ORDER BY forms_donnees.rang
=> donne les bons résultats avec HAVING res=6 !!
SELECT forms_donnees.id_form, forms_donnees.id_donnee, COUNT(forms_donnees.id_donnee) AS res, donnees_champs.valeur AS id_mot
FROM `test`.spip_forms_donnees AS `forms_donnees`, `test`.spip_forms_donnees_champs AS `dc`, `test`.spip_forms_donnees_champs AS `donnees_champs`, `test`.spip_forms_champs AS `champs`
WHERE (forms_donnees.id_form = '3')
AND (forms_donnees.confirmation = "valide")
AND (forms_donnees.statut = "publie")
AND ((dc.champ='mot_1' AND dc.valeur='62') OR (dc.champ='mot_3' AND dc.valeur IN ('5','31')))
AND (dc.id_donnee = forms_donnees.id_donnee)
AND (forms_donnees.id_form = champs.id_form)
AND (champs.type = "mot")
AND (donnees_champs.champ = champs.champ)
AND (donnees_champs.id_donnee = forms_donnees.id_donnee)
GROUP BY forms_donnees.id_donnee, forms_donnees.id_donnee
HAVING res=3
ORDER BY forms_donnees.rang
=> donne les bons résultats avec HAVING res=6 !!
Modified:
_plugins_/_stable_/forms/forms_et_tables_1_9_1/public/forms_boucles.phpModified: _plugins_/_stable_/forms/forms_et_tables_1_9_1/public/forms_boucles.php
--- _plugins_/_stable_/forms/forms_et_tables_1_9_1/public/forms_boucles.php (original)
+++ _plugins_/_stable_/forms/forms_et_tables_1_9_1/public/forms_boucles.php Tue Apr 17 13:09:56 2007
@@ -66,7 +66,7 @@
$boucle = &$boucles[$idb];
if ($not)
erreur_squelette(_T('zbug_info_erreur_squelette'), $crit->op);
- $boucle->modificateur['crit_filtre'] = 1;
+ $boucle->modificateur['crit_filtre'] = !isset($crit->param[0]) ? "'ET'" : calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
//$boucle->where= array("'='", "'$boucle->id_table." . "id_parent'", 0);
}
@@ -106,22 +106,29 @@
$boucle->hash .= <<<code
$reqfiltre
\$filtre = "";
+ \$res = 0;
while (\$row = @spip_abstract_fetch(\$result,"")){
if ((\$r = _request(\$row['champ']))!==NULL){
if (is_array(\$r)){
+ \$r = array_diff(\$r,array('')); // enlever les valeurs vides
+ \$res += count(\$r);
if (strlen(implode("",\$r))) - \$filtre .= " AND (dc.champ="._q(\$row['champ'])." AND dc.valeur IN (".implode(',',array_map('_q',\$r))."))";
+ \$filtre .= " OR (dc.champ="._q(\$row['champ'])." AND dc.valeur IN (".implode(',',array_map('_q',\$r))."))";
}
- elseif (strlen(\$r))
- \$filtre .= " AND (dc.champ="._q(\$row['champ'])." AND dc.valeur="._q(\$r).")";
+ elseif (strlen(\$r)){
+ \$res++;
+ \$filtre .= " OR (dc.champ="._q(\$row['champ'])." AND dc.valeur="._q(\$r).")";
}
}
- if (strlen(\$filtre)) \$filtre = substr(\$filtre,5);
+ }
+ if (strlen(\$filtre)) \$filtre = '('.substr(\$filtre,4).')';
else \$filtre="1=1";
code;
+ $boucle->select = 'COUNT('.$boucle->id_table . '.id_donnee) AS res';
$boucle->where = '$filtre';
$boucle->from["dc"] = "spip_forms_donnees_champs";
$boucle->where = array("'='", "'dc.id_donnee'", "'$id_table.id_donnee'");
+ $boucle->having = '('.$boucle->modificateur['crit_filtre'].'!="OU")?"res=$res":"1=1"';
$boucle->group = $boucle->id_table . '.id_donnee'; }
_______________________________________________
Spip-zone-commit@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone-commit