MySQL GROUP_CONCAT: Formater la sortie
-
06-07-2019 - |
Question
J'ai actuellement la requête suivante:
SELECT group_concat(DISTINCT usrFirst, usrLast) as receiver_name //etc
Lors de l'utilisation de PHP, il affiche ma liste de noms comme suit:
<?php
echo $row['receiver_name'];
//Outputs: JohnDoe,BillSmith,DaveJones
//Desired output: John Doe, Bill Smith, and Dave Jones
J'ai besoin d'aide pour déterminer trois choses:
-
Comment puis-je insérer un espace entre le prénom et le nom?
-
Comment insérer un espace après chaque virgule?
-
Comment puis-je ajouter un 'et' juste avant le nom de famille affiché?
La solution
Je ne suis pas sûr que vous deviez inciter MySQL à faire exactement ce que vous voulez là-bas. Je suggère d'utiliser les éléments suivants:
SELECT DISTINCT CONCAT(first, ' ', last) AS receiver_name
FROM names;
Parcourez ensuite cet ensemble de résultats en PHP et gérez les cas "et" là-bas.
Si les performances sont un problème (vous ferez souvent cette requête). Vous auriez intérêt à ne pas utiliser DISTINCT sur la valeur calculée de CONCAT (premier, '', dernier) car cela nécessiterait l'utilisation d'une table temporaire.
Pour le modifier, ajoutez l'index suivant:
ALTER TABLE names ADD INDEX (last, first);
Et modifiez votre requête comme suit:
SELECT CONCAT(first, ' ', last) AS receiver_name
FROM names
GROUP BY last, first;
Vous pourrez obtenir vos valeurs directement à partir de l'index sans recourir à une table temporaire ou à un portier de fichiers.
En ce qui concerne la boucle, les éléments suivants fonctionneraient:
<?php
$mysqli = new mysqli(/* connection info */);
$sql = "SELECT CONCAT(first, ' ', last) AS receiver_name "
. 'FROM names '
. 'GROUP BY last, first';
if ($result = $mysqli->query($sql)) {
$string = '';
$count = $result->num_rows;
$rows = $result->fetch_all();
for ($i = 0; $i < $count-1; $i++) {
$string .= $rows[$i][0] . ', ';
}
$string .= ' and ' . $rows[$i][0];
echo $string; // John Smith, Bob Dole, and George Bush
}
Remarque Ce code suppose que vous ayez toujours au moins 2 lignes renvoyées. Je suis sûr que vous pouvez comprendre comment gérer le cas d'un seul nom renvoyé. :)
Autres conseils
SELECT GROUP_CONCAT(CONCAT_WS(' ', usrFirst, usrLast)) as receiver_name
FROM (
SELECT DISTINCT usr_first, usr_last
FROM mytable
) q
Cette solution distinguera 'Smith, John Davis'
et 'Davis Smith, John'
(renverra 'John Davis Smith'
deux fois, pas une fois, car ce sont des personnes différentes).