2011-01-11 2 views
0

좋아, 여기 내 문제가있다. 프로젝트 노트를 저장하기 위해 기존 데이터베이스에 테이블을 추가하고 있습니다.제대로 MySQL 테이블을 조인하는 방법을 이해하는 데 문제가

는 "worklog는"프로젝트 "worklognotes"와 테이블 프로젝트와 테이블이

노트는 토론 스레드 표시가 나타납니다 노트입니다. worklognotes 열은이 ID, worklog_id, timestamp, notes처럼 설정됩니다.

"id"는 고유 ID 테이블입니다. "worklog_id"는 메모가 소유하고있는 프로젝트의 ID로 다른 테이블에 저장됩니다. "timestamp"는 타임 스탬프입니다. "notes"는 프로젝트에 대한 실제 진행 메모입니다. 하나의 프로젝트에 많은 메모가있을 수 있습니다.

아래의 데이터베이스 쿼리를 살펴보십시오. 나는 두 가지 질문에 "처음 가입 했으니 까." 두 테이블의 정보를 읽고 표시하고 있습니다. 하지만 아래 코드는 "worklognotes"테이블에 레코드가있는 "worklog"의 모든 항목을 표시합니다. "worklog"에서 한 항목을 표시하고 "worklognotes"에서 많은 메모를 표시해야합니다.

방향을 도우시겠습니까?

$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

이 내게 도움 : http://www.codinghorror.com/ blog/2007/10/a-visual-explanation-of-sql-joins.html – PostMan

+0

4 개의 공백으로 들여 쓰기하고 \'를 사용하여 인라인 코드를 래핑하여 코드를 포맷하십시오. (편집기에서 코드 버튼 ('{})을 시도하십시오.) – Kissaki

+0

예 및 아니오 작업 로그 및 작업 인식 목록에서 정보를 가져옵니다. 그러나 아래 코드는 "worklognotes"테이블에 레코드가있는 "worklog"의 모든 항목을 표시합니다. – KingMob

답변

2

JOIN을 만드는 쿼리는 올바른 것처럼 보이지만 where 절은 중복됩니다. 이 시도 : 특정 요구 사항에 대한 그러나

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

에 가입 할 필요가있을 것 같지 않습니다 (다른 하나 개 테이블과 여러 레코드에서 하나 개의 레코드를 가져 오는). 두 개의 개별 쿼리를 실행하는 것이 가장 좋습니다. 그렇지 않으면 결과 세트의 모든 행에서 첫 번째 테이블의 모든 데이터가 반복됩니다.

+0

나는 그것을 먼저 시도하고 그것을 올바르게하는 것이 어려워. – KingMob

1

당신은 가장 가능성 싶어 :이 만 ID가 $의 worklog_id (예를 들어, 57)에 저장 한 작업 로그 및/모든 관련 worklog 노트를 끌어

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

, 최신 표시 먼저.

당신이 원하는 작업 로그를 정확하게 지정하지 않았기 때문에 쿼리가 모든 작업 로그와 모든 worklognotes를 가져오고있었습니다. 단지 worklognote가 있어야한다는 것입니다.

0

아래의 데이터베이스 쿼리를 살펴보십시오. 나는 두 개의 쿼리에 합류했습니다. "내 첫 번째 참여이므로 나는 지금 을 완료했는지 확신 할 수 없습니다." 두 테이블에서 정보를 읽고 정보를 표시하고 있습니다. 그러나 아래의 코드는 "worklog" "worklognotes"테이블에 레코드가있는 의 모든 항목을 표시하는 입니다. 나는

예, 당신이 가입 할 때 어떻게 작동하는지 이잖아 디스플레이에 "worklognotes"에서 "worklog"에서 하나 개의 항목 및 많은 노트를해야합니다. 작업 로그 항목과 worklognotes 항목을 단일 행으로 가져올 것입니다. 이것은 하나의 worklognote 만있는 경우가 아니면 동일한 작업 로그 항목을 여러 번 가질 것임을 의미합니다. 어떤 종류의 계층 구조로 표시하려면 PHP 측에서이를 정렬해야합니다.모든 worklogs (또는 jsut보다 더 진짜)과 메모를 원하는 경우

그래서 당신은 예 $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과 쿼리 단순화 할 수 있습니다 귀하의 열 이름에 따라 하나의 작업 항목 당 행과 concatinated와 함께 구분 모든 메모를 줄 것이다 가입 :

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

자연 결합은 standart sql이 아니지만 매우 유용한 도구입니다. 2 개의 테이블이 공통적으로 가지고있는 컬럼이 정확히 1 개있는 경우, WHERE 절이있는 내부 조인과 같이 결합됩니다. GROUP_CONCAT에

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

상세 사항 : 다른 구분자를 사용하려면

내가 SQL 학습 때

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

관련 문제