MySQL GROUP_CONCAT: форматирование вывода - PullRequest
2 голосов
/ 31 июля 2009

У меня сейчас следующий запрос:

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. Как я могу добавить 'и' прямо перед отображением фамилии?

Ответы [ 2 ]

5 голосов
/ 31 июля 2009
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' дважды, а не один раз, поскольку они разные люди).

3 голосов
/ 31 июля 2009

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

...