Frage

Alles, was ich bisher gesehen habe, geht darum, doppelte Einträge in einer Datenbank automatisch zu entfernen. Ich möchte zu Beginn betonen, dass dies das ist Es gibt keine doppelten Daten in der Datenbank. Ich werde auch mit der Tatsache beginnen, dass ich immer noch etwas über RDBMS -Design, Normalisierung, Beziehungen und vor allem SQL lerne!

Ich habe eine Client -Tabelle mit einer ClientID (PK) und einem Client_Name. Ich habe eine Rollentabelle mit einem Rollen- (PK) und einem Rollennamen. Jeder Client kann mehrere Rollen zugeordnet haben. Also habe ich eine Client_Role_Link -Tabelle mit ClientID und Rollen -ID als zwei Feldern erstellt. Dann leite ich das:

SELECT client.client_name, role.role_name FROM client 
  LEFT JOIN client_role_link ON client_role_link.clientid=client.clientid 
  LEFT JOIN role ON client_role_link.roleid=role.roleid 
  WHERE (role.roleid='1' OR role.roleid='2')

Nehmen wir also an, ich habe einen Kunden mit zwei Rollen (Rollen '1' und '2'). Diese Abfrage gibt zwei Zeilen zurück, eine für jede Rolle. Wenn ich diese Ergebnisse zurück bekomme, verwende ich a while Schleife, um die Ergebnisse durchzuführen und sie in a auszugeben <select> aufführen. Es verursacht dann zwei <option>'s mit demselben Client aufgeführt.

Ich verstehe, warum meine Frage zwei Zeilen zurückgibt, es macht Sinn. Hier kommt also die zweifache Frage:

  1. Gibt es ein besseres Datenbank-/Tabellendesign, das ich verwenden sollte, oder eine optimiertere Abfrage?
  2. Oder soll ich das im PHP bewältigen? Wenn ja, gibt es eine elegantere Lösung, die alle Ergebnisse in ein Array hinzufügen, dann durch das Array zurückgehen und Duplikate entfernen?

Gedanken?

War es hilfreich?

Lösung

Wenn Sie beide Rollen zeigen möchten, dann ist Ihre Frage OK.

MySQL unterstützt Array -Datentypen nicht, daher sollten Sie ein assoziatives Array auf dem füllen PHP Seite mit dem Ergebnis mit den doppelten Clientnamen.

Wenn Sie nur Kunden zeigen müssen, die eine der Rollen haben, verwenden Sie diese Abfrage:

SELECT  c.*
FROM    client c
WHERE   c.clientid IN
        (
        SELECT  roleid
        FROM    client_role_link crl
        WHERE   crl.roleid IN (1, 2)
        )

Dies gibt einen Datensatz pro Kunden zurück, wird jedoch keine Rollen angezeigt.

Der dritte Weg würde die Rollennamen auf der Serverseite implodieren:

SELECT  c.*, GROUP_CONCAT(role_name SEPARATOR ';') AS roles
FROM    client c
LEFT JOIN
        client_role_link crl
ON      crl.clientid = c.clientid
        AND crl.roleid IN (1, 2)
LEFT JOIN
        role r
ON      r.roleid = crl.roleid
GROUP BY
        c.id

und explodieren Sie sie weiter PHP Seite, aber stellen Sie sicher, dass die Rollennamen nicht mit dem Separator mischen.

Andere Tipps

Du könntest benutzen mysql_fetch_assoc () um sie wieder in Array -Form zu bringen. Dann könntest du so etwas haben wie Code ungetestet, kann aber funktionieren:

$sql = "SELECT client.id, client.client_name, role.role_name FROM client LEFT JOIN client_role_link ON client_role_link.clientid=client.clientid LEFT JOIN role ON client_role_link.roleid=role.roleid WHERE (role.roleid='1' OR role.roleid='2')";
$result = mysql_query($sql);
$res = array();
while ($row = mysql_fetch_assoc($result)) {
    $res[$row['id']]['roles'][] = $row['role_name'];
    $res[$row['id']]['client_name'] = $row['client_name']; //you'll be overwriting each iteration probably a better way
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top