MySQL GROUP_CONCAT: форматирование вывода
-
06-07-2019 - |
Вопрос
У меня сейчас следующий запрос:
SELECT group_concat(DISTINCT usrFirst, usrLast) as receiver_name //etc
При использовании PHP он выводит мой список имен следующим образом:
<?php
echo $row['receiver_name'];
//Outputs: JohnDoe,BillSmith,DaveJones
//Desired output: John Doe, Bill Smith, and Dave Jones
Мне нужна помощь в выяснении трех вещей:
<Ол>Как я могу поставить пробел между именем и фамилией?
Как вставить пробел после каждой запятой? Р>
Как я могу добавить 'и' прямо перед отображаемой фамилией? Р>
Решение
Я не уверен, что вы должны заставить MySQL делать именно то, что вам нужно. Я бы предложил использовать следующее:
SELECT DISTINCT CONCAT(first, ' ', last) AS receiver_name
FROM names;
Затем переберите этот набор результатов в PHP и обработайте регистр 'и' там.
Если важна производительность (вы будете часто делать этот запрос). Вам было бы полезно не использовать DISTINCT для вычисленного значения CONCAT (first, '', last), поскольку это потребовало бы использования временной таблицы.
Чтобы настроить его, добавьте следующий индекс:
ALTER TABLE names ADD INDEX (last, first);
И измените ваш запрос следующим образом:
SELECT CONCAT(first, ' ', last) AS receiver_name
FROM names
GROUP BY last, first;
Вы сможете получать свои значения непосредственно из индекса, не прибегая к временной таблице или сортировке файлов.
Что касается цикла, то будет работать что-то вроде следующего:
<?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
}
Примечание . В этом коде предполагается, что вам всегда будет возвращено как минимум 2 строки. Я уверен, что вы можете понять, как обрабатывать регистр только с одним возвращенным именем. :) Р>
Другие советы
SELECT GROUP_CONCAT(CONCAT_WS(' ', usrFirst, usrLast)) as receiver_name
FROM (
SELECT DISTINCT usr_first, usr_last
FROM mytable
) q
Это решение будет различать «Смит, Джон Дэвис»
и «Дэвис Смит, Джон»
(вернет «Джон Дэвис Смит»
дважды, а не один раз, так как они разные люди).