Valeurs multiple pour une colonne d'un SELECT

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Valeurs multiple pour une colonne d'un SELECT

par Jeannot1974 » 26 août 2005, 17:41

Bon je pense que j'ai trouvé le principe de la solution à adopter pour mon problème. :idea:

En fait je vais adapter ma fonction d'export XLS, et passer 2 requêtes en paramètre.
:arrow: La première constituera la base de ma feuille XLS, celle à partir de laquelle je détermine le titre (entre autre) de mes colonnes, à laquelle j'ajouterai systématiquement une colonne supplémentaire, qui contiendra par la suite ma LISTE.
:arrow: Lors de l'itération de constitution des lignes, je "capturerai" le code ident de la ligne, qui servira de paramètre à l'exécution de la deuxième requête, établissant pour la dernière colonne, ma liste.

Bon ça c'est la théorie, faut le mettre en oeuvre... ce sera pas avant lundi, mais je vous communiquerai le code...

Finalement, c'est donc bien une soluce PHP qu'il aura fallut adopter.... comme quoi y'a que les imbéciles qui changent pas d'avis ;-)

Merci à vous

par Jeannot1974 » 26 août 2005, 17:28

Le problème de la rupture dans le 2e WHILE vient du fait qu'il s'agit de code PHP, et que ma fonction attend du SQL.

Je pense que je vais m'orienter vers une nouvelle fonction XLS comme en parle AUGURE...

Je vous tiens au courant...

par iclo » 26 août 2005, 17:20

Désolé mais il y a un truc qui me chiffone : je ne comprends où est le problême d'interger une rupture de séquence dans le 2ème while ??

par Augure » 26 août 2005, 17:20

Sinon, tu peux ré écrire une fonction d'export vers XLS qui prend en paramétre un tableau à 2 dimensions. Cette fonction pourrait être ré utilisé pour tes autres requêtes complexe.

Réponse à AUGURE

par Jeannot1974 » 26 août 2005, 17:17

Ta solution collerai un peu plus avec mon besoin... j'examine la chose...

Merci

par Jeannot1974 » 26 août 2005, 17:12

Bon en fait ça colle pas avec mon besoin...

La raison pour laquelle je souhaite que cela se fasse dans UNE SEULE REQUETE SQL, est simple, c'est pour générer un fichier XLS ayant en entrée UNE SEULE REQUETE et non pas UNE FONCTION....

Ci-après la dite fonction :
function export_XLS($req, $Fnm, $db) {
		//include("fct_nettoiexls.php");	
		nettoie_XLS();
		// Calcul la date et l'heure de génération du fichier EXCEL
		$date = date("Ymd-His");
		// Composition du nom unique du fichier EXCEL
		$Fnm = "export/".$date."_".$Fnm;
		//$Fnm = "export/".$Fnm;
		
		if (file_exists($Fnm)) {  
	  		unlink($Fnm);
	  	}
		// Ouverture du fichier en ecriture
		$inF = fopen($Fnm,"w+");
		
		fputs($inF,"<table border='1'>\n");
			
		if ($req) {
			$res = mysql_db_query($db,$req) or die ("MESSAGE d'ERREUR : ".mysql_error(). " - ".$req);
			$i = 0;
			
			//Construction de l'entete du tableau
			$chaine = "<tr bgcolor='#EECC11'>";
			while ($i < mysql_num_fields($res)) {
				$meta = mysql_fetch_field($res, $i);
				if (!$meta) {
					echo "Aucun champ n'est disponible<br>\n";
				}
				$chaine .= "<th>".$meta->name."</th>";
				$i++;
			}
			$chaine .= "</tr>";
			fputs($inF,$chaine);
			
			while ($row = mysql_fetch_array($res)) {
				$chaine = "<tr>";
				for ($i=0 ; $i < mysql_num_fields($res) ; $i++) {
					$chaine .= "<td>".$row[$i]."</td>";	
				}
				$chaine .= "</tr>\n";
				fputs($inF,$chaine);
			}
		}
		else {
			echo "Aucune requête n'a été spécifiée...";
		}
		fputs($inF,"</table>");

		fclose($inF);
		
		return $Fnm;
	}
Aux vus de ce code, tu comprends bien, qu'il est difficile (voire impossible d'adopter ta solution (qui est très bonne cependant)).

Bref, c'est pas encore ça, mais on progresse... En fait la soluce serait de faire une boucle au niveau des champs du SELECT, mais c'est pas possible, donc faut trouver une autre solution...

Je suis sur une autre piste, et je te tiendrais au courant si j'ai la solution...

par Augure » 26 août 2005, 17:00

Heu .... si la réponse doit être en SQL pur c'est moi qui ai raison. Si tu veux que se soit simple .... j'ai tout faux. Prends la solution PHP ;-)

par Augure » 26 août 2005, 16:58

Salut,

Le SQL est incapable de faire de l'itératif pur (c'est à dire se rappeller lui même, ou dans notre cas concaténer par ligne n colonnes à la suite avec n différent d'une ligne à l'autre)

Par contre on peut tricher un peu si tu connais le nombre max d'itération que tu peux avoir. Dans notre cas, y a t il un nombre max de CB par CA ?

Voici un exemple de la solution à la quelle je pense. Dans cette exemple on suppose qu'il y a 3 niveau max

Code : Tout sélectionner

Select C.CA, Case count(*) when 1 then ( Select C2.CB From C2 Where C2.CA=C.CA LIMIT 0 TO 1 ) when 2 then ( Select C2.CB From C2 Where C2.CA=C.CA LIMIT 0 TO 1 ) +( Select C2.CB From C2 Where C2.CA=C.CA LIMIT 1 TO 2 ) when 3 then ( Select C2.CB From C2 Where C2.CA=C.CA LIMIT 0 TO 1 ) +( Select C2.CB From C2 Where C2.CA=C.CA LIMIT 1 TO 2 ) +( Select C2.CB From C2 Where C2.CA=C.CA LIMIT 2 TO 3 ) else 'etc ....' end From C Group By C.CA
PS : Attention le couple AB est toujours unique, donc tu ne peux pas afficher A.Code_A as 'CodeTableA'
et à la fois B.Nom_ChampB as 'LibelleTableB'

PS : cette syntaxe fonctionne sur la base SYBASE ASE. Je ne l'ai pas porté sur MySQL. Mais "Cas When Then Else End" existe sous MySQL t il un nombre max de 1,2,3, .... ?

par Jeannot1974 » 26 août 2005, 16:45

OK, je fais quelques tests et je te tiens au courant...

Merci...

par iclo » 26 août 2005, 16:36

si tu récupère un result set qui ressemble à ceci :
A B
1 1
1 2
1 3
1 4
2 1
2 2
2 3
2 4

et que tu veux arriver à ceci
1 : 1,2,3,4
2 : 1,2,3,4

c'est une simple question d'affichage :
En gros ça donne ceci :
$idA ="";
while ($resultat = mysql_fetch_array($req)){
   // si c'est un nouveau codeA, on passe à la ligne et on l'affiche 
   if ($id !=  $resultat['CodeTableA']) {
       print "<br>".$resultat['CodeTableA']." : ";
       $id =$resultat['id'];
    }
    print " ".$resultat['CodeTableB'];
}     
J'ai pas eu le temps de tester, mais l'idée doit y être :D :D
Tu devras surement adapter un peu...

par Jeannot1974 » 26 août 2005, 14:07

Donc voici la requête "expurgée" :

Code : Tout sélectionner

SELECT A.Code_A as 'CodeTableA', B.Nom_ChampB as 'LibelleTableB', FROM TableA A LEFT JOIN TableC C ON (A.Code_A = C.Code_C) LEFT JOIN TableB B ON (C.Code_C = B.Code_B) WHERE A.Code_A = #valeur#
Voila voila...
(désolé pour le délai, mais le poste de dév, et celui d'accès au net ne sont pas connectés...)

par Jeannot1974 » 26 août 2005, 13:58

Ah, tu m'interesses... quel "gueule" ça a ta solution ?

PS : Je prépare ma requête, et la poste dans la foulée...

par iclo » 26 août 2005, 12:18

Je n'ai pas parler de faire plusieurs select, mais d'utiliser une rupture de séquence( avec un test à chaque itération)

par Jeannot1974 » 26 août 2005, 12:15

Concernant la rupture en afficahge, ça je sais faire...

Mon souci, c'est que pour des raisons "techniques" de production d'une feuille Excel, je dois faire cela en une seule requête.

Je ne peux pas faire un SELECT, le parcourir, et faire ensuite un autre SELECT en fonction de la valeur du moment...

Donc cette solution n'est pas possible... Merci quand même...

Je vais expurger ma requête actuelle des données sensibles et je la posterai de retour de ma pause déjeuner... A tout de suite...

par iclo » 26 août 2005, 12:07

Il te suffit de faire un simple select.

C'est lors de l'affichage que tu vas gêrer ça, avec une rupture de séquence dans la boucle qui effetuera l'affichage:
Si la valeur CA est différente de la valeur précédente, tu commences une nouvelle ligne et tu affiches CA.

Maintenant tout dépend de ce que tu veux faire exactement