MySQLをいじめて、そこでやりたいことを正確に実行する必要があるかどうかはわかりません。以下を使用することをお勧めします。
SELECT DISTINCT CONCAT(first, ' ', last) AS receiver_name
FROM names;
次に、PHP でこの結果セットをループし、' と ' のケースを処理します。
パフォーマンスが問題になる場合 (このクエリを頻繁に実行することになります)。一時テーブルを使用する必要があるため、CONCAT(first, ' ', last) の計算値に DISTINCT を使用しないことでメリットが得られます。
微調整するには、次のインデックスを追加します。
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 行が返されることを前提としています。名前が 1 つだけ返された場合の処理方法を理解できるはずです。:)