Rassembler plusieurs lignes sql en php
Résolu
Mireilla
-
Mireilla -
Mireilla -
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 :
Merci :)
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 :)
A voir également:
- 'String_agg' n'est pas une option nom de fonction intégrée reconnue.
- Partager photos en ligne - Guide
- Mètre en ligne - Guide
- Comment rassembler plusieurs fichiers pdf en un seul - Guide
- Écrire plusieurs lignes dans une cellule excel mac - Guide
- Excel trier par ordre alphabétique en gardant les lignes - Guide
2 réponses
yg_be
Messages postés
23541
Date d'inscription
Statut
Contributeur
Dernière intervention
Ambassadeur
1 584
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
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
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 :
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 :
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
Xavier
PS : Un point important : rien ne te garantit que les morceaux de phrases n'arrivent dans le bon ordre...
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...
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...
Penses-tu que c'est une bonne démarche?
La je suis complètement bloqué sur ce truc :(
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 :(
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 :
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 :
Il peut y avoir des erreurs, je n'ai pas de serveur php sous la main pour tester...
Xavier
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
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
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
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 :
Ici, $where corresponds a ma recherche de mot clé.
Cordialement.