2012-04-09 20 views
1

Ich habe Schwierigkeiten, eine elegante Lösung zum Sortieren der Ergebnisse einer MySQL-Abfrage basierend auf einer begrenzten Zeichenfolge zu finden. Ill erklären im Detail weiter untenSortierung der Ergebnisse einer MySQL-Abfrage

Ich erstelle eine Datenbank von Kontakten, in denen einzelne Benutzer Leute von einer Liste hinzufügen/entfernen können. Wenn der Benutzer einen neuen Kontakt hinzufügt ich anhängen den zusätzlichen Kontakt-ID an einen getrennten String und speichern, die Daten in einer Datenbankspalte mit dem Benutzer zugeordnet ist (benannt Kontakte):

$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 

Wenn der Benutzer sucht ihre Kontakte, die ich das packen Daten aus der Spalte Kontakte, explodieren/spaltete die Zeichenfolge und geben die einzelnen Benutzer-Namen:

$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>'); 
} 

in der Tat alle Namen dieser zurückkehrt, aber es gibt sie in der Reihenfolge der getrennten Zeichenfolge. Ich finde nicht, dass ich eine elegante Möglichkeit finde, alphabetisch nach Namen zu sortieren.

Sollte ich die Kontaktliste nicht in einer Zeichenfolge mit Trennzeichen speichern? Wie würdest du das lösen?

+1

Sie sollten Ihre Kontakte in einer neuen Tabelle namens Kontakte speichern. Jede Zeile dieser Tabelle sollte die Benutzer-ID haben, also können Sie 'SELECT * FROM \' contacts \ 'WHERE \ 'user_id \' = verwenden; ' –

+0

Die Datenbank normalisieren und die Sortierung sollte ziemlich einfach sein . – Zoredache

+0

Diese Art von Problem ist genau deshalb, warum Sie Einträge in einer Datenbank nicht als kommagetrennte Zeichenfolge speichern sollten. normalisieren! normalisieren! normalisieren! –

Antwort

2

Sie haben Recht, Sie sollten die Kontakte nicht in einer Zeichenfolge speichern. Verwenden Sie stattdessen eine andere Tabelle, die die Benutzerinformationen enthält. Die neue Tabelle sollte in etwa wie folgt aussehen:

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

Dann, wenn Sie Ihre Kontaktliste benötigen ausführen können Sie einfach eine andere Abfrage:

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

Oder aber Sie es bestellen müssen.

2

Es gibt zwei offensichtliche Ansätze:

  1. sortieren die Ergebnisse, sobald Sie sie
  2. holen sie alle in einer Abfrage und haben Art der DB ihnen

Für 1 # geholt haben, verwenden 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>'); 
} 

Für # 2, bauen eine Liste von IDs und verwenden 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

Wenn Sie eine relationale Datenbank verwenden, dann, was Sie wollen, ist eine separate Tabelle, die Person-Kontaktbeziehungen speichert. Dann würden Sie Ihre SQL-Abfrage ändern auf einem wählen basierend kommen über zwei Tabellen

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 

(Dieser Code ist wahrscheinlich nicht ganz richtig.)

Wenn Sie mit einem No-SQL-Typ Implementierung, die So wie Sie es machen, ist es in Ordnung, nur dass Sie entweder nach der Tat oder nach dem Sortieren sortieren müssen. Sortierung bei Einfügung bedeutet, dass Sie die aktuelle Liste der Kontakte nach dem Einfügen abfragen und dann durchsortieren müssen, um die richtige Position zu finden und die ID in die Trennzeichenfolge einzufügen. Dann speichern Sie das zurück in die Datenbank. Der Nachteil ist, dass Sie nur in eine Richtung sortieren können.

Im Allgemeinen verwenden Leute relationale Datenbanken und "normalisieren" sie wie oben beschrieben.

Verwandte Themen