2011-01-11 35 views
0

好的,這裏是我的問題。 我正在向現有數據庫添加一個表來存儲項目備註。理解如何正確加入mySQL表的問題

「工作日誌」是與項目 「worklognotes」表是與項目表指出

的音符會被顯示成一個話題。 worklognotes列設置爲像這樣的id,worklog_id,timestamp,notes。

「id」是表的唯一ID。 「worklog_id」是備註存儲在另一個表中的項目的ID。 「時間戳」就是時間戳 「註釋」是關於項目的實際正在進行的註釋。一個項目可能會有很多筆記。

查看下面的數據庫查詢。我已經加入了兩個問題「這是我第一次加入,所以我不確定我是否做對了。」 它讀取兩個表中的信息並顯示它。 但下面的代碼顯示了在「worklognotes」表中有記錄的「worklog」中的每個條目。 我需要它從「工作日誌」和許多來自「工作日誌」的筆記中顯示一個條目

您能幫助或建議一個方向嗎?

$connection = mysql_connect ("localhost", "user", "pass") or die ("I cannot connect to the database."); 
$db = mysql_select_db ("database", $connection) or die (mysql_error()); 

$query = "SELECT * FROM worklog "; 
$query .= "JOIN worklognotes ON worklog_id = worklognotes.worklog_id "; 
$query .= "WHERE worklognotes.worklog_id=worklog.id ORDER BY worklognotes.id DESC"; 
+0

這幫助我,當我在學習SQL:http://www.codinghorror.com/ blog/2007/10/a-visual-explanation-of-sql-joins.html – PostMan 2011-01-11 21:30:57

+0

請使用4個空格縮進並用\`包裝內嵌代碼來格式化代碼。 (在編輯器中嘗試編碼按鈕(`{}`)。) – Kissaki 2011-01-11 21:32:16

回答

2

您所查詢的創建JOIN看起來是正確的,但你的where子句是多餘的。試試這個:

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

不過,對於您的具體要求(取從另一個從一個表和多個記錄的一個記錄)似乎沒有成爲一個需要參加。我認爲最好是運行兩個單獨的查詢,否則您將從結果集的每一行中重複第一個表中的所有數據。

1

你最有可能想:

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

這將僅抽出已經存儲在$ worklog_id(比如57)的ID的工作日誌,以及任何/所有相關的工作日誌記錄,顯示最新的第一。

您查詢被拔除所有worklogs和ALL worklognotes,因爲你沒有確切你想要的工作日誌說明,只是他們必須有一個worklognote。

0

查看下面的數據庫查詢。我 已經加入了兩個查詢「這是我的 第一次加入,所以我不知道我做了 它是正確的。」它正在讀取兩個表中的 信息,並顯示 。但是,下面的代碼是 顯示在「工作日誌」 每個條目已在 「worklognotes」表中的記錄。我需要它 顯示從「工作日誌」一個條目和 許多筆記「worklognotes」

對,就是當你加入它是如何工作的。您將會將工作日誌條目和工作日誌條目視爲單行。這意味着你將有多次相同的工作日誌條目,除非它只有一個工作日誌。如果你想在某種層次結構中顯示,你需要在PHP端進行排序。

所以,如果你希望所有worklogs(或比僅僅指剛一個更加真實地)和他們的筆記,你會用你的查詢,然後遍歷結果,然後適當地組織例如假設$result是您的mysql_result資源和$worklog_columns$worklognote_columns含有格式'column_name' => null列名的每個表的數組,那麼你可能會做一些這樣的:

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

但是你必須要知道的事情是,如果兩個表您選擇加入與列相同的名稱,那麼如果你使用MYSQL_ASSOC,你只會從加入的ta的列中獲得值而不是來自兩者。如果您需要訪問兩個表上的值,則您需要在查詢中使用MYSQL_NUM或MYSQL_BOTH或別名。

1

這就是聯接的工作原理。每個有效組合將得到一行。最接近你想要的就是彙集所有的工作筆記。

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

這會給你每工作項只有一行,並串連並與分隔所有音符,

根據您的列名您可以簡化您有ntural查詢聯接:

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

自然連接不是標準的SQL,但它是一個非常方便的工具。 如果有兩個表共有的EXCELLY ONE COLUMN,它將作爲內部連接與where子句一起加入。

如果你想使用其他分隔符:在GROUP_CONCAT

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

詳情:

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