1

区切られた文字列に基づいて mysql クエリの結果をソートするエレガントなソリューションを見つけようとするのは困難です。以下で詳しく説明します

個々のユーザーがリストから人を追加/削除できる連絡先のデータベースを作成しています。ユーザーが新しい連絡先を追加すると、追加された連絡先 ID を区切られた文字列に追加し、そのデータをそのユーザー (連絡先という名前) に関連付けられたデータベース列に格納します。

$userID = ?? //YOUR ID
$contactID = ?? //WHATEVER THE ADDED USER ID IS
$confirm = 0 //has the user been confirmed
$sql = "SELECT contacts FROM user WHERE id = '$userID'";
$query = mysql_query($sql);
$row = mysql_fetch_array($query);
$contact = $row['contacts']; 
$contact .= '|'.$contactID.':'.$confirm;
$update = mysql_query("UPDATE user SET contacts = '$contact' WHERE id = '$userID'");

//contact column data might be:  |10:0|18:0|36:0|5:0

ユーザーが連絡先を検索すると、連絡先列からデータを取得し、文字列を分解/分割して、個々のユーザー名を返します。

$userID = ?? //YOUR ID
$sql = "SELECT contacts FROM user WHERE id = '$userID'";
$query = mysql_query($sql);
$row = mysql_fetch_array($query);
$contacts = explode("|", $row['contacts']);
foreach($contacts as $item)
{
 list($contactID,$confirm) = split(":", $item);
 $sql = "SELECT name FROM ".user." WHERE id = '$contactID'";  
 $query = mysql_query($sql);
 $row = mysql_fetch_array($query);
 echo($row['name'].'<BR>');
}

これは確かにすべての名前を返しますが、区切り文字列の順序で返します。名前をアルファベット順に並べ替えるエレガントな方法が見つからないようです。

連絡先リストを区切り文字列で保存するべきではありませんか? これをどのように解決しますか?

4

3 に答える 3

2

2つの明白なアプローチがあります:

  1. 結果を取得したら、結果を並べ替えます
  2. それらすべてを1つのクエリで取得し、DBに並べ替えさせます

#1には、次を使用しますusort()

$rows = array();
foreach ($contacts as $item){
    list($contactID,$confirm) = split(":", $item);
    $query = mysql_query("SELECT name FROM user WHERE id = '$contactID'");
    $rows[] = mysql_fetch_array($query);
}
usort($rows, 'sort_by_name');

function sort_by_name($a, $b){
    return strcmp($a['name'], $b['name']);
}

foreach ($rows as $row){
    echo($row['name'].'<BR>');
}

#2の場合、IDのリストを作成し、以下を使用しますIN

$ids = array();
foreach ($contacts as $item){
    list($contactID,$confirm) = split(":", $item);
    $ids[] = $contactID;
}
$ids = implode(',', $ids);
$query = mysql_query("SELECT name FROM user WHERE id IN ($ids) ORDER BY name ASC");
while ($row = mysql_fetch_array($query)){

    echo($row['name'].'<BR>');
}
于 2012-04-09T20:04:51.137 に答える
2

そうです、連絡先を文字列に保存するべきではありません。代わりに、ユーザー情報を含む別のテーブルを使用してください。新しいテーブルは次のようになります。

Table: user_contacts
| user_id    |    contact_id    | confirm |
-------------------------------------------
|  your data here...                      |

次に、連絡先リストが必要な場合は、別のクエリを実行するだけです。

SELECT * FROM `user_contacts`
JOIN `users` ON `users`.`id` = `user_contatcs`.`user_id`
WHERE `users`.`id` = $id
ORDER BY `users`.`name`;

または、しかしあなたはそれを注文する必要があります。

于 2012-04-09T20:04:18.087 に答える
1

リレーショナルデータベースを使用している場合、必要なのは、個人と連絡先の関係を格納する別のテーブルです。次に、SQLクエリを変更して、2つのテーブル間の結合に基づいて選択します

SELECT * FROM person, contact
JOIN contact ON person.id = contact.personid
JOIN person ON contact.contactid = person.id
WHERE person.id = $id
ORDER BY person.lastname 

(そのコードはおそらく完全には正しくありません。)

no-sqlタイプの実装を使用している場合は、プログラムで事後にソートするか、挿入時にソートする必要があることを除いて、それを実行する方法は問題ありません。挿入時に並べ替えとは、連絡先の現在のリストを挿入時にクエリし、並べ替えて正しい位置を見つけ、区切り文字列にIDを挿入する必要があることを意味します。次に、それをデータベースに保存します。これの欠点は、一方向にしかソートできないことです。

一般に、人々はリレーショナルデータベースを使用し、上記のようにそれらを「正規化」します。

于 2012-04-09T20:08:17.583 に答える