2012-04-09 111 views
1

在试图找出一个优雅的解决方案来排序基于分隔字符串的mysql查询结果时遇到困难。我在下面更详细地解释对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>'); 
} 

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

我不应该将联系人列表存储在分隔字符串中吗?你会如何解决这个问题?

+1

您应该将联系人存储在称为“联系人”的新表格中。这个表的每一行都应该有用户ID,所以你可以使用'SELECT * FROM''contacts'WHERE \'user_id''<用户ID here>;' – 2012-04-09 20:03:59

+0

正确地规范数据库,排序应该很容易。 – Zoredache 2012-04-09 20:04:18

+0

这种问题恰恰就是为什么您不应将条目存储在数据库中作为逗号分隔的字符串。归!归!归! – 2012-04-09 20:26:19

回答

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`; 

或者无论你需要订购。

2

有两个明显的方法:

  1. 排序的结果,一旦你拿来他们
  2. 获取它们都在同一个查询,并有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>'); 
} 
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 

加入(该代码可能是不太正确的。)

如果您使用的是无SQL类型的实现中,你做的方式很好,除非你必须以编程方式在事实之后排序,或者按照插入排序。对插入进行排序意味着您必须在插入一个联系人时查询当前联系人列表,然后进行排序以找到正确的位置并将ID插入分隔字符串中。然后将其保存回数据库。缺点是你只能按一种方式排序。

一般来说,人们使用关系数据库并按上面所述“归一化”它们。