Я потратил слишком много времени, пытаясь найти хорошее решение этой проблемы самостоятельно. Не нашли хороших ответов, чтобы помочь, хотя я безуспешно пытался найти решения из разных ответов.
Цель: представить страницу проектов с разбивкой по страницам, содержащую данные из нескольких
столы.
Я использую несколько объединений в одном запросе MYSQL, потому что я хотел избежать выполнения запросов в цикле PHP. Уже одно это привело к проблеме fetch_assoc, когда мне пришлось создать собственный массив результатов из while(fetch_assoc)
цикл из-за повторяющихся строк в результате запроса. Однако следующая проблема заключается в том, что запрос выполняется через класс разбиения на страницы, который я использую для генерации ссылок на страницы и получения данных запроса, таких как num_rows и тому подобное.
Итак, сейчас у меня есть страница, показывающая нужные мне данные, но класс разбивки на страницы показывает мне неправильное количество строк и ссылок на страницы. Не уверен, что лучший способ обойти эту проблему. Надеемся получить некоторые идеи от одного из вас, блестящих экспертов!
Код в основном:
$sql = "...."
$projects = new pager($sql)
echo $projects->num_rows
while($projects->fetch_assoc){
build new array from data
$project_array[][][]
}
foreach($project_array){
display data from all tables...
}
$projects->showPageLinks
это SQLFiddle предоставляет пример данных, которые я получаю:
Обратите внимание, что есть 7 строк результатов, но только для 4 проектов. Таким образом, класс разбиения на страницы показывает 7 num_rows (по праву), но есть только 4 проекта.
Любые идеи приветствуются!
Хотя, возможно, я объединяю результаты подзапроса из других таблиц в строковые значения в собственных столбцах и анализирую их с помощью php explode()
и тому подобное, которое затем получило бы отдельные строки проекта со всеми данными, но я пока не смог этого сделать.
Заранее спасибо за вашу помощь!
Единственное решение, которое мне удалось найти, — объединить результаты подзапросов / объединений в отдельные столбцы в основном наборе результатов. Это позволяет мне получать результаты, которые мне нужны, без необходимости изменять класс нумерации страниц.
Смотрите пример связанных результатов в этом SQLFiddle
Пример запроса:
SELECT p.id pid, p.name pname, c.name cname,
GROUP_CONCAT(DISTINCT CONCAT_WS('|',w.hours,w.notes,t.name) SEPARATOR ';') as works
FROM projects p
LEFT JOIN (SELECT * FROM clients) AS c ON c.id=p.client_id
LEFT JOIN (SELECT * FROM work) AS w ON w.project_id=p.id
LEFT JOIN (SELECT * FROM tools) AS t ON t.id=w.tool_id
GROUP BY p.id
GROUP_CONCAT(DISTINCT ...
это то, что объединяет отдельные строки из объединенных результатов, и CONCAT_WS('',col,col,..)
объединяет отдельные столбцы результатов. Оба позволяют вам использовать разделители, которые вы определяете, так же, как php implode()
было бы. В конечном итоге вы получаете отформатированную строку результатов в одном столбце / строке, в которой вы можете использовать php для explode()
строки, а затем их столбцы.
Теперь я получаю правильное количество результатов и просто разбиваю строки и поля с помощью определенных разделителей.
Пример кода:
$wkeys = array('hours','notes','toolname'); // to use as array key (column name)
while($r=$projects->fetch_assoc()){
if(strpos($r['works'],';')!==false){
$wrows = explode(";",$r['works']); // individual rows
foreach($wrows as $k=>$v) {
$wv = explode("|",$v); // individual col=val pairs
$works[] = array_combine($wkeys,$wv);
}
}
}
Надеюсь, что это помогает кому-то еще, кто может столкнуться с той же ситуацией.
РЕДАКТИРОВАТЬ: Хотя это решение работает довольно хорошо для меня, я столкнулся с проблемой с ограничением длины по умолчанию для GROUP_CONCAT
1024. Любое значение, превышающее 1024, было сокращено до 1024. См. этот ответ чтобы решить это. Я бы посоветовал вам проявить инициативу и изменить ее сейчас, если только вы не уверены, что ваши значения никогда не будут больше 1024.
Других решений пока нет …