Rassembler plusieurs lignes sql en php

Résolu/Fermé
Mireilla - 18 juil. 2017 à 15:30
 Mireilla - 24 juil. 2017 à 10:38
Bonjour toute la communauté,

Je voulais savoir, si quelqu'un serait comment on peut rassembler plusieurs lignes qui sont identiques.

En effet, quand je fais un SELECT*FROM avec mes tables(3tables) et mes colonnes que je veux j'arrive à tout ressortir avec les 3 colonnes que je veux, comme Prenom, Pays et Commentaire.

Donc les résultats s'affiche de cette manière :

Prenom : Machin
Pays: Italie
Commentaire: aujourd'hui

Prenom : Machin
Pays: Italie
Commentaire: 18/07/17

Prenom : Machin
Pays: Italie
Commentaire: il fait beau

Prenom : Truc
Pays: France
Commentaire: aujourd'hui

Prenom : Truc
Pays: France
Commentaire: 17/07/17

Prenom : Truc
Pays: France
Commentaire: il fait beau


En fonction de ces tables :

Table commentaire:

ID Numéro Type Commentaire

1 6 36 aujourd'hui
1 6 36 18/07/2017
1 6 36 il fait beau

2 7 3 aujourd'hui
2 7 3 17/07/2017
2 7 3 il fait beau


Table pays:

ID_pays pays ville ID

1 Italie Rome 1
2 France Paris 2


<gras>Table client gras>

ID_nom NOM Prenom ID

1 Truc Machin 1
2 Machin Truc 2



Merci :)

2 réponses

yg_be Messages postés 23342 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 21 novembre 2024 Ambassadeur 1 550
18 juil. 2017 à 19:28
bonsoir,
Si je comprends bien, tu nous montres ce que tu obtiens comme réponse.
Pourrais-tu nous montrer également:
- la source SQL de ta requête
- ce que tu souhaites obtenir comme réponse
0
Bonjour,

Désolé hier j'ai eu un soucis informatique, impossible de me connecter bref,
en effet il manque une partie dans mon énoncé.

J'avais mit également ce que je voulais mais je viens de voir que ca n'a pas fonctionné.

Je voudrais que la réponse soit écrite de cette façon :

Prenom : Machin
Pays: Italie
Commentaire: aujourd'hui 18/07/17 il fait beau


Prenom : Tuc
Pays: Italie
Commentaire: aujourd'hui 17/07/17 il fait beau


Ma requête est écrite de cette façon :

$maRequete = ("SELECT * FROM dbo.[commentaire] LEFT OUTER JOIN dbo.[pays] ON dbo.[commentaire].ID = dbo.[pays].ID
LEFT OUTER JOIN dbo.[client] ON dbo.[client].ID= dbo.[commentaire].ID WHERE $where");


Ici, $where corresponds a ma recherche de mot clé.

Cordialement.
0
Reivax962 Messages postés 3672 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
20 juil. 2017 à 10:04
Bonjour,

Tu as deux solutions.

Soit concaténer au niveau SQL la colonne commentaire en faisant un GROUP BY ID, Numéro. La syntaxe va dépendre de ton SGBD. Malheureusement, il me semble que tu es sous SQL Server... Dans une version (très) récente, tu peux utiliser STRING_AGG. Sinon c'est beaucoup plus complexe. Avec STRING_AGG :
SELECT cl.Prenom, p.Pays, co.ID, STRING_AGG(co.commentaire, ' ') as commentaire
FROM  dbo.[commentaire] co
LEFT OUTER JOIN dbo.[pays] p ON co.ID = p.ID
LEFT OUTER JOIN dbo.[client] cl ON cl.ID= co.ID
WHERE $where
GROUP BY cl.Prenom, p.Pays, co.ID


C'est la solution la plus propre à mon goût, mais si tu n'as pas STRING_AGG, le mieux est de trier les résultats par co.ID, puis, au niveau du php, de réaliser la concaténation en n'affichant le résultat qu'à chaque changement d'ID.
Pour ça ta requête SQL devient :
SELECT * FROM dbo.[commentaire]
LEFT OUTER JOIN dbo.[pays] ON dbo.[commentaire].ID = dbo.[pays].ID
LEFT OUTER JOIN dbo.[client] ON dbo.[client].ID= dbo.[commentaire].ID WHERE $where"
ORDER BY dbo.[commentaire].ID

Et dans ton php, au lieu de faire des "echo" à chaque ligne, tu gardes dans des variables les valeurs, y compris ID, et en début de boucle tu vérifies si l'ID en cours est le même que l'ID en mémoire ; si c'est le même, tu fais
$commentaire .= ' ' . $row['commentaire']
(à adapter à tes noms de variables), sinon tu fais tes echo.

Xavier

PS : Un point important : rien ne te garantit que les morceaux de phrases n'arrivent dans le bon ordre...
0
Bonjour Xavier,

Tout d'abord merci pour ta réponse !

J'ai donc essayer ta première proposition car je suis bien sous du SQL SERVER mais pas la toute dernière des versions.

J'ai donc une erreur sur le STRING_AGG qui est sqlsrv_query: message = [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]'STRING_AGG' n'est pas une option nom de fonction intégrée reconnue.


Voici le code que j'ai créé pour avoir cette réponse...
<?php 

//Ma recherche par mot clef
if(isset($_GET['submit'])){
$comment = htmlspecialchars(trim($_GET['comment']));

if(empty($comment)){
echo"<span class='errors'>Veuillez remplir ce champs</span>";
}else if(strlen($comment)==1){// si l'utilisateur rentre juste une lettre la recherche affiche un message d'erreur
echo"<span class='errors'>Votre mot clé de recherche est trop court</span>";
}else{

$where = ' ';
$comment = preg_split('/[\s\-]/', $comment);
$count_keywords = count($comment);

foreach ($comment as $key => $comments) {
$where .= "Comment LIKE '% $comments %'";//$comments = n'importe quel mot clef
if($key != ($count_keywords-1)){
$where .= " AND ";
}
}

$maRequete = ("SELECT 'Cl.prenom', 'P.pays', 'CO.commentaire', STRING_AGG('CO.commentaire', '') AS commentaire FROM dbo.[commentaire ] CO
LEFT OUTER JOIN dbo.[pays] P ON CO.ID = P.ID
LEFT OUTER JOIN dbo.[client]Cl ON Cl.ID = CO.ID
WHERE $where
GROUP BY CO.commentaire");
//$where = Liens entre les tables et le mot rechercher => 18/07/17

$query=sqlsrv_query($conn, $maRequete);
$rows = sqlsrv_num_rows($query);

if($rows === false){

while($search = sqlsrv_fetch_array($query, SQLSRV_FETCH_ASSOC)){
$p=$search['prenom'];
$ps=$search['pays'];
$c=$search[commentaire];
$i=0;
$c = str_ireplace($comments,'<span class="surlign">'.$comments.'</span>', $p);//Met en gras le mot rechercher dans la colonne "comment" 18/07/17
$d = str_ireplace($comments,'<span class="surlign">'.$comments.'</span>', $ps);//Met en gras le mot rechercher dans la colonne "description"
$n = str_ireplace($comments,'<span class="surlign">'.$comments.'</span>', $c);//Met en gras le mot rechercher dans la colonne "name"

//affiche les résultats de la recherche 18/07/2017

echo"<strong>Prénom : </strong> $c";
echo"<br /> <strong>Pays : </strong> $d";
echo"<br /> <strong> Commentaire : </strong> $n <br /><br />";


}

}else{
echo"<strong>Il n'y a pas de résultat trouvé...</strong>"; // Affiche cette phrase si rien n'a été trouvé
}

}
}

?>


Penses-tu que c'est une bonne démarche?

La je suis complètement bloqué sur ce truc :(
0
Je pense donc que je ne peux pas utiliser un STRING_AGG
0
Reivax962 Messages postés 3672 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
21 juil. 2017 à 15:21
Bonjour,

Alors, sur le principe, ta requête n'est pas bonne, car le GROUP BY ne doit pas porter sur le champ agrégé, mais au contraire sur tous les autres :
		$maRequete = ("SELECT Cl.prenom, P.pays, STRING_AGG(CO.commentaire, ' ') AS commentaire FROM  dbo.[commentaire] CO
                              LEFT OUTER JOIN dbo.[pays] P ON CO.ID = P.ID
                              LEFT OUTER JOIN dbo.[client] Cl ON Cl.ID = CO.ID
                              WHERE $where 
                              GROUP BY Cl.prenom, P.pays"); 	

Ceci dit, vu le message d'erreur on est plutôt dans ce que je craignais : ta version de SQL Server n'est pas assez récente, et cette fonction est inconnue.

Il va te rester la deuxième solution : l'agrégation directement en PHP.
Essaie quelque chose comme ça :
		$maRequete = ("SELECT CO.ID, Cl.prenom, P.pays, CO.commentaire FROM dbo.[commentaire] CO
					LEFT OUTER JOIN dbo.[pays] P ON CO.ID = P.ID
					LEFT OUTER JOIN dbo.[client]Cl ON Cl.ID = CO.ID
					WHERE $where 
					ORDER BY CO.ID");

		$query=sqlsrv_query($conn, $maRequete);
		$rows = sqlsrv_num_rows($query);
			
		if($rows === false){

			$id_courant = false;
			$commentaire = '';
			$prenom = '';
			$pays = '';
			while($search = sqlsrv_fetch_array($query, SQLSRV_FETCH_ASSOC)){
				if ($id_courant === false) {	// Initialisation
					$id_courant = $search['ID'];
					$prenom = $search['prenom'];
					$pays = $search['pays'];
					$commentaire = $search['commentaire'];
				}
				elseif ($id_courant == $search['ID']) {
					// On reste sur le même ID. On se contente de rajouter le nouveau morceau de commentaire.
					$commentaire .= ' ' . $search['commentaire'];
				}
				else {
					// Changement d'ID ! On affiche les données courantes...
					$c = str_ireplace($comments,'<span class="surlign">'.$comments.'</span>', $prenom);//Met en gras le mot rechercher dans la colonne "comment" 18/07/17
					$d = str_ireplace($comments,'<span class="surlign">'.$comments.'</span>', $pays);//Met en gras le mot rechercher dans la colonne "description"
					$n = str_ireplace($comments,'<span class="surlign">'.$comments.'</span>', $commentaire);//Met en gras le mot rechercher dans la colonne "name"
					echo"<strong>Prénom : </strong> $c";
					echo"<br /> <strong>Pays : </strong> $d";
					echo"<br /> <strong> Commentaire : </strong> $n <br /><br />";
					
					// ... et on les change
					$id_courant = $search['ID'];
					$prenom = $search['prenom'];
					$pays = $search['pays'];
					$commentaire = $search['commentaire'];
				}
			}
			// Et on n'oublie pas le tout dernier 
			$c = str_ireplace($comments,'<span class="surlign">'.$comments.'</span>', $prenom);//Met en gras le mot rechercher dans la colonne "comment" 18/07/17
			$d = str_ireplace($comments,'<span class="surlign">'.$comments.'</span>', $pays);//Met en gras le mot rechercher dans la colonne "description"
			$n = str_ireplace($comments,'<span class="surlign">'.$comments.'</span>', $commentaire);//Met en gras le mot rechercher dans la colonne "name"
			echo"<strong>Prénom : </strong> $c";
			echo"<br /> <strong>Pays : </strong> $d";
			echo"<br /> <strong> Commentaire : </strong> $n <br /><br />";
		}


Il peut y avoir des erreurs, je n'ai pas de serveur php sous la main pour tester...

Xavier
0
Mireilla > Reivax962 Messages postés 3672 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021
24 juil. 2017 à 08:38
Merci pour ta réponse,

je vais essayez ca :) et je te redis ca :)

Bonne journée !
0
re bonjour,

Bon j'ai essayer comme tu as fait mais j'ai deux erreurs assez particulière qui sont :


Warning: sqlsrv_num_rows() expects parameter 1 to be resource, boolean given

Warning: sqlsrv_fetch_array() expects parameter 1 to be resource, boolean given


Je n'arrive pas a trouver de quoi ca vient...


Merci de ton aide
0