ОБЪЕДИНЕНИЕ ГРУПП MySQL: Форматирование вывода


В настоящее время у меня есть следующий запрос:

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

Мне нужна помощь в выяснении трех вещей:

  1. Как я могу поставить пробел между именем и фамилией?

  2. Как вставить пробел после каждой запятой?

  3. Как я могу добавить "и" прямо перед отображаемой фамилией?

Author: Peter O., 2009-07-31

2 answers

Я не уверен, что вам следует заставлять MySQL делать именно то, что вы хотите. Я бы предложил использовать следующее:

SELECT DISTINCT CONCAT(first, ' ', last) AS receiver_name
FROM names;

Затем просмотрите этот набор результатов в PHP и обработайте случай "и" там.

Если вас беспокоит производительность (вы будете часто выполнять этот запрос). Вам было бы полезно не использовать DISTINCT для вычисляемого значения CONCAT (первый, '', последний), так как для этого потребуется использовать временную таблицу.

Чтобы настроить его, добавьте следующее индекс:

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 строк. Я уверен, что вы сможете понять, как справиться со случаем, когда возвращается только одно имя. :)

 3
Author: hobodave, 2009-07-31 16:37:49
SELECT  GROUP_CONCAT(CONCAT_WS(' ', usrFirst, usrLast)) as receiver_name
FROM    (
        SELECT  DISTINCT usr_first, usr_last
        FROM    mytable
        ) q

Это решение будет различать 'Smith, John Davis' и 'Davis Smith, John' (вернет 'John Davis Smith' дважды, а не один раз, так как они разные люди).

 5
Author: Quassnoi, 2009-07-31 16:34:06