我很难找到一个优雅的解决方案来根据分隔的字符串对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>');
}
这确实会返回所有名称,但它会以分隔字符串的顺序返回它们。我似乎找不到按字母顺序按名称排序的优雅方式。
我是否应该将联系人列表存储在分隔的字符串中?你怎么解决这个问题?
答案 0 :(得分: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`;
或者你需要订购它。
答案 1 :(得分:2)
有两种明显的方法:
对于#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>');
}
答案 2 :(得分:1)
如果您正在使用关系数据库,那么您想要的是一个存储人与人之间联系关系的单独表。然后,您将修改您的SQL查询以基于两个表的连接选择
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插入到分隔的字符串中。然后将其保存回数据库。这样做的缺点是你只能单向排序。
通常,人们使用关系数据库并按上述方式“标准化”它们。