Проблемы с пониманием того, как правильно присоединиться к таблицам MySQL - PullRequest
0 голосов
/ 12 января 2011

Хорошо, вот моя проблема. Я добавляю таблицу в существующую базу данных для хранения заметок проекта.

"worklog" - таблица с проектами "worklognotes" - таблица с примечаниями проекта

Примечания будут отображаться в виде темы обсуждения. Столбцы worklognotes настроены так: id, worklog_id, timestamp, notes.

«id» - уникальный идентификатор таблицы. «worklog_id» - это идентификатор проекта, к которому относится заметка, которая хранится в другой таблице. «отметка времени» - это хорошо отметка времени «заметки» - это текущие текущие заметки о проекте. В одном проекте может быть много заметок.

Глядя на запрос базы данных ниже. Я присоединился к двум запросам: «Это мое первое объединение, поэтому я не уверен, что все сделал правильно». Это чтение информации в обеих таблицах и отображение ее. Но приведенный ниже код отображает каждую запись в «рабочем журнале», в которой есть запись в таблице «рабочих журналов». Мне нужно, чтобы отображалась одна запись из «журнала работ» и много заметок из «журнала работ»

Можете ли вы помочь или предложить направление?

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

Ответы [ 4 ]

2 голосов
/ 12 января 2011

Ваш запрос на создание JOIN выглядит правильно, но ваше предложение where является избыточным.Попробуйте это:

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

Однако для ваших конкретных требований (выборка одной записи из одной таблицы и нескольких записей из другой), кажется, нет необходимости объединяться.Я думаю, что лучше всего выполнить два отдельных запроса, иначе вы получите все данные из первой таблицы, повторенные в каждой строке в вашем наборе результатов.

1 голос
/ 12 января 2011

Так работает объединение. Вы получите один ряд для каждой действительной комбинации. Самое близкое, что вы можете получить к тому, что вы хотите, - это агрегирование всех рабочих записей.

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

Это даст вам только одну строку для каждого рабочего элемента, и все заметки будут объединены и отделены,

В зависимости от имен столбцов вы можете упростить запрос с помощью естественного объединения:

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

Естественное объединение не является стандартным SQL, но это очень удобный инструмент. Если столбец EXACTLY ONE одинаков для двух таблиц, он объединит их как внутреннее соединение с предложением where.

Если вы хотите использовать другой разделитель:

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

Подробная информация о GROUP_CONCAT:

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

1 голос
/ 12 января 2011

Скорее всего, вы захотите:

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), и все / все связанные примечания к рабочему журналу, сначала отображаемые самыми новыми.

Ваш запрос извлекал ВСЕ рабочие журналы и ВСЕ рабочие журналы, поскольку вы не указали, какой именно рабочий журнал вы хотите, просто им нужно было иметь рабочую заметку.

0 голосов
/ 12 января 2011

Глядя на запрос базы данных ниже. я присоединились к двум запросам "Это мое сначала присоединиться, так что я не уверен, что я сделал это правильно. "Это чтение информация в обеих таблицах и показывая это. Но приведенный ниже код отображение каждой записи в «рабочем журнале» который имеет запись в Таблица «Рабочие журналы». Мне нужно это отобразить одну запись из «рабочего журнала» и много заметок из "рабочих заметок"

Да, вот как это работает, когда вы присоединяетесь. Вы получите запись рабочего журнала и запись рабочих заметок в виде одной строки. Это означает, что у вас будет одна и та же запись рабочего журнала несколько раз, если только у нее нет только одной рабочей заметки. Вам нужно разобраться с этим на стороне php, если вы хотите отобразить в какой-то иерархии.

Таким образом, если вы хотите, чтобы все рабочие журналы (или больше, чем 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, вы получите значение только из столбца объединенной таблицы, а не из обеих. Если вам нужен доступ к значению обеих таблиц, вам нужно либо использовать MYSQL_NUM или MYSQL_BOTH, либо псевдоним каждого столбца в вашем запросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...