Хорошо, вот моя проблема. Я добавляю таблицу в существующую базу данных для хранения заметок по проекту.
«worklog» — это таблица с проектами «worklognotes» — это таблица с примечаниями к проекту
Заметки будут отображаться как цепочка обсуждений. Столбцы worklognotes настроены как этот идентификатор, worklog_id, метка времени, заметки.
"id" - это уникальный идентификатор таблицы. «worklog_id» — это идентификатор проекта, к которому относится заметка, которая хранится в другой таблице. "Временная метка" - это хорошо. "Заметки" с временной меткой - это фактические текущие заметки о проекте. К одному проекту может быть много заметок.
Глядя на запрос базы данных ниже. Я присоединился к двум запросам: «Это мое первое присоединение, поэтому я не уверен, что сделал это правильно». Он читает информацию в обеих таблицах и отображает ее. Но приведенный ниже код отображает каждую запись в «рабочем журнале», которая имеет запись в таблице «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";
4 ответа
Ваш запрос на создание JOIN выглядит правильно, но ваше предложение where является избыточным. Попробуй это:
SELECT *
FROM worklog
JOIN worklognotes ON worklog_id = worklognotes.worklog_id
ORDER BY worklognotes.id DESC
Однако для ваших конкретных требований (извлечение одной записи из одной таблицы и нескольких записей из другой) кажется, что нет необходимости в присоединении. Я думаю, что лучше всего запускать два отдельных запроса, иначе вы получите все данные из первой таблицы, повторяющиеся в каждой строке вашего набора результатов.
Скорее всего, вы хотите:
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), и любые/все связанные заметки рабочего журнала, самые новые отображаются первыми.
Ваш запрос вытягивал ВСЕ рабочие журналы и ВСЕ рабочие журналы, поскольку вы не указали, какой именно рабочий журнал вы хотите, просто у них должен был быть рабочий журнал.
Вот как работает соединение. Вы получите одну строку для каждой допустимой комбинации. Самое близкое к тому, чего вы хотите, — это объединение всех рабочих заметок.
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, но это очень удобный инструмент. Если есть ТОЛЬКО ОДИН столбец, общий для двух таблиц, он соединит их так же, как внутреннее соединение с предложением 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
Глядя на запрос базы данных ниже. Я присоединился к двум запросам: «Это мое первое присоединение, поэтому я не уверен, что сделал это правильно». Он читает информацию в обеих таблицах и отображает ее. Но приведенный ниже код отображает каждую запись в «рабочем журнале», которая имеет запись в таблице «worklognotes». Мне нужно, чтобы отображалась одна запись из «рабочего журнала» и много заметок из «рабочего журнала».
Да, вот как это работает, когда вы присоединяетесь. Вы получите запись рабочего журнала и запись worklognotes в виде одной строки. Это означает, что у вас будет одна и та же запись рабочего журнала несколько раз, если только в ней нет только одной записи рабочего журнала. Вам нужно разобраться с этим на стороне php, если вы хотите отображать в какой-то иерархии.
Поэтому, если вам нужны все рабочие журналы (или больше, чем один) и их заметки, вы должны использовать имеющийся у вас запрос, а затем перебирать результаты для организации, а затем, например, предположить, что $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, либо использовать псевдоним для каждого столбца в вашем запросе.
Похожие вопросы
Новые вопросы
php
PHP — это широко используемый язык сценариев общего назначения с открытым исходным кодом, мультипарадигмальный, динамически типизированный и интерпретируемый, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.
{}
) в редакторе.)