2011-01-11 6 views
0

Ok, hier ist mein Problem. Ich füge eine Tabelle zu einer vorhandenen Datenbank hinzu, um Projektnotizen zu speichern.Problem zu verstehen, wie mySQL-Tabellen ordnungsgemäß zu verbinden

„worklog“ ist die Tabelle mit den Projekten „worklognotes“ ist die Tabelle mit dem Projekt stellt fest

Die Noten werden wie ein Diskussionsthread angezeigt werden. worklognotes Spalten sind wie diese ID, worklog_id, Timestamp, Notizen eingerichtet.

"ID" ist die Tabelle eindeutige ID. "worklog_id" ist die ID des Projekts, für das die Notiz vorhanden ist und die in einer anderen Tabelle gespeichert ist. "timestamp" ist gut ein Timestamp "Notizen" sind die tatsächlichen laufenden Notizen über das Projekt. Es könnte viele Notizen zu einem einzelnen Projekt geben.

Blick auf die Datenbank Abfrage unten. Ich habe mich den zwei Fragen angeschlossen "Es ist mein erster Beitritt, also bin ich mir nicht sicher, ob ich es richtig gemacht habe." Es liest die Informationen in beiden Tabellen und zeigt sie an. Der folgende Code zeigt jedoch jeden Eintrag in "worklog" an, der einen Eintrag in der Tabelle "worklognotes" enthält. Ich brauche es, um einen Eintrag von "worklog" und viele Notizen von "worklognotes" anzuzeigen

Können Sie helfen oder eine Richtung vorschlagen?

+0

Dies half mir, wenn ich SQL lernte: http://www.codinghorror.com/ blog/2007/10/a-visuelle-erklärung-von-sql-joins.html – PostMan

+0

Bitte formatieren Sie den Code, indem Sie ihn mit 4 Leerzeichen einrücken und den Inline-Code mit \ 'einschließen. (Try Code-Taste ('{}') im Editor.) – Kissaki

+0

Ja und Nein. Es erhält die Informationen aus dem Worklog und Arbeitsnotizen. Der folgende Code zeigt jedoch jeden Eintrag in "worklog" an, der einen Datensatz in der Tabelle "worklognotes" enthält. – KingMob

Antwort

2

Ihre Abfrage zum Erstellen des JOIN sieht korrekt aus, aber Ihre WHERE-Klausel ist redundant. Versuchen Sie folgendes:

SELECT * 
FROM worklog 
JOIN worklognotes ON worklog_id = worklognotes.worklog_id 
ORDER BY worklognotes.id DESC 

jedoch für Ihre spezifischen Anforderungen (Abrufen einen Datensatz aus einer Tabelle und mehrere Datensätze von einem anderen) es scheint nicht notwendig zu sein, zu verbinden. Ich denke, es ist am besten, zwei separate Abfragen auszuführen, sonst werden alle Daten aus der ersten Tabelle in jeder Zeile in Ihrer Ergebnismenge wiederholt.

+0

Ich versuchte es zuerst und was hatte Probleme, es richtig zu machen. – KingMob

1

Sie würden höchstwahrscheinlich wollen:

SELECT * 
FROM worklog 
LEFT JOIN worklognotes ON worklog_id = worklognotes.worklog_id 
WHERE worklog_id = $worklog_id 
ORDER BY worklognotes.timestamp DESC; 

Dies wird nur die Arbeitsprotokoll herausziehen, die die ID in $ worklog_id (sagen wir, 57), und alle/alle zugehörigen worklog Notizen gespeichert hat, angezeigt neueste zuerst.

Ihre Abfrage löste ALLE Worklogs und ALLE Worklognotes aus, da Sie nicht genau angegeben haben, welches Worklog Sie haben möchten, nur dass sie ein WorkLognote haben müssen.

0

Blick auf die Datenbankabfrage unten. I haben die beiden Abfragen verbunden "Es ist meine ersten Beitritt, so dass ich nicht sicher bin, habe ich getan es richtig gemacht." Es liest die Informationen in beiden Tabellen und zeigt es an. Aber der folgende Code ist Anzeige jeden Eintrag in "worklog" , die einen Datensatz in der "worklognotes" -Tabelle hat. Ich muss es Anzeige einen Eintrag von „worklog“ und viele Noten von „worklognotes“

Ja, das ist, wie es funktioniert, wenn Sie beitreten. Sie erhalten den Worklog-Eintrag und einen Worklogotes-Eintrag als einzelne Zeile. Dies bedeutet, dass Sie denselben Arbeitsbucheintrag mehrmals haben werden, es sei denn, er hat nur einen Arbeitsnotizwert. Sie müssen dies auf der PHP-Seite aussortieren, wenn Sie in irgendeiner Art von Hierarchie angezeigt werden möchten.

Also, wenn Sie alle Worklogs (oder mehr als jsut ein wirklich) wollen und ihre Notizen, die Sie würde die Abfrage Sie verwenden und dann über die Ergebnisse iterieren dann in geeigneter Weise zu organisieren, zum Beispiel $result nehmen wird Ihre mysql_result Ressource und $worklog_columns und $worklognote_columns enthalten ein Array der Spaltennamen für jede Tabelle im Format 'column_name' => null dann könnten Sie etwas tun, wie folgt aus:

$worklog = array(); 

while(false !== ($record = mysql_fetch_assoc($result))){ 
    // get only the data for a worklognote 
    $note = array(array_intersect_key($result, $worklognote_columns)); 

    // get the primary key of the worklog 
    $id = $record['worklog_id']; 


    if(!isset($worklog[$id])){ 
    // if we havent already processed this worklog form a previous row 

    // get the work log data in a separate array 
    $log = array_intersect_key($result, $worklog_columns); 

    // add a notes key which will hold an array of worklog_notes 
    // and assifn the note joined to this row as the first note 
    $log['notes'] = array($note); 
    } 
    else 
    { 
    // otherwise jsut append the not joined to this row 
    // to the existing worklog we processed 
    $worklog[$id]['notes'][] = $note; 
    } 
} 

jedoch das, was Sie sich bewusst sein müssen, ist, dass, wenn die beiden Tabellen youre Verbindungs ​​haben Spalten mit Wenn Sie MYSQL_ASSOC verwenden, erhalten Sie nur den Wert aus der Spalte der verknüpften ta ble, nicht von beiden. Wenn Sie Zugriff auf den Wert für beide Tabellen benötigen, müssen Sie entweder MYSQL_NUM oder MYSQL_BOTH oder alias jede Spalte in Ihrer Abfrage verwenden.

1

So funktioniert ein Join. Sie erhalten eine Zeile für jede gültige Kombination. Der nächste, den Sie erreichen können, ist, dass Sie alle Arbeitsnotizen zusammenstellen.

SELECT workitem.workID, GROUP_CONCAT(worknotes.note) 
FROM `workitem` 
JOIN worknotes ON worknotes.workID = workitem.workID 
GROUP BY workID 

Diese Sie geben nur eine Zeile pro workitem und alle Noten mit verkettet und getrennt,

auf Spaltennamen Je Sie in der Lage sein, kann man mit einem ntural Abfrage zu vereinfachen verbinden:

SELECT workID, GROUP_CONCAT(worknotes.note) 
FROM `workitem` 
NATURAL JOIN worknotes 
GROUP BY `workID` 

Natürliche Join ist nicht standard sql, aber es ist ein sehr handliches Werkzeug. Wenn es genau eine Spalte gibt, die die beiden Tabellen gemeinsam haben, wird sie nur als innere Verknüpfung mit einer where-Klausel verknüpft.

Wenn Sie eine andere seperator verwenden möchten:

SELECT workID, GROUP_CONCAT(worknotes.note SEPARATOR '; ') 
    FROM `workitem` 
    NATURAL JOIN worknotes 
    GROUP BY `workID` 

Details zu GROUP_CONCAT:

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat