对mysql查询的结果进行排序

时间:2012-04-09 20:00:04

标签: php mysql search sorting

我很难找到一个优雅的解决方案来根据分隔的字符串对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>');
}

这确实会返回所有名称,但它会以分隔字符串的顺序返回它们。我似乎找不到按字母顺序按名称排序的优雅方式。

我是否应该将联系人列表存储在分隔的字符串中?你怎么解决这个问题?

3 个答案:

答案 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. 获取结果后对结果进行排序
  2. 在一个查询中获取所有内容并让数据库对其进行排序
  3. 对于#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插入到分隔的字符串中。然后将其保存回数据库。这样做的缺点是你只能单向排序。

通常,人们使用关系数据库并按上述方式“标准化”它们。