PHP и вывод результатов «один ко многим»

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

В моей базе данных есть ряд URL-адресов, которые получены по запросу SELECT вместе с различными другими полями из разных таблиц. Каждый url имеет по крайней мере одну связанную с ним категорию, но может иметь несколько категорий. Поэтому в моих результатах я мог бы увидеть что-то похожее на это:

link_id = 3 url= 'http://www.somesite1.com' category = 'uncategorised' link_id = 4 url= 'http://www.somesite2.com' category = 'travel' link_id = 4 url= 'http://www.somesite2.com' category = 'fun' link_id = 4 url= 'http://www.somesite2.com' category = 'misc' link_id = 3 url= 'http://www.somesite3.com' category = 'uncategorised' 

У меня есть это для работы. Когда я прокручиваю и распечатываю их, используя цикл while и mysql fetch, результат выглядит точно так же, как и выше. Это здорово, за исключением того, что мне нужно, чтобы он читал что-то вроде:

 link_id = 4 url = 'http://www.somesite2.com' category = 'travel fun misc' 

Так что в основном все категории для каждого URL-адреса получаются как-то, так как они распечатываются. Моя первая попытка заставила меня попробовать вложенный цикл while, но это не сработало, и я не уверен, насколько это возможно. Кроме того, мне интересно, может ли мне понадобиться многомерный массив (полная догадка, мне никогда не приходилось использовать его раньше).

Я заказываю эти результаты по идентификатору ссылки, как указано выше, поэтому я знаю, соответствует ли идентификатор ссылки в текущей итерации цикла, соответствует ли она последней в последней итерации – тогда у меня есть что-то, что имеет более чем одну категорию. Я думаю, что я действительно близко, но я просто не могу понять.

Есть идеи?

Существует также функция GROUP_CONCAT в mysql. Это должно делать именно то, чего вы хотите достичь.

Что-то вроде :

 SELECT url, GROUP_CONCAT(category) AS categories FROM yourtable GROUP BY url 

Вы должны использовать таблицу соединений.

1-й у вас есть таблица ссылок

 id = 1 url = something id = 2 url = something else 

Затем у вас есть таблица категорий

 id = 1 category = something id = 2 category = something else 

Затем у вас есть таблица соединений

 url_id = 1 category_id = 1 url_id = 1 category_id = 2 url_id = 2 category_id = 1 

Это должно по крайней мере начать вас.

вам нужно использовать алгоритм прерывания управления.

 set last_link variable to null set combined_category to null exec query loop over result set { if last_link == null { last_link=fetch_link } if fetch_link==last_link { set combined_category+=ltrim(' '.fetch_category) } else { display html for last_link and combined_category set last_link=fetch_link set combined_category=fetch_category } }//loop display html for last_link and combined_category 

Я использовал «display html» в качестве общего «рабочего» события, вы могли бы вывести его из массива и т. Д. Вместо этого …

используйте массив, привязанный к id и url, итерации через значения и добавьте к нему следующее:

 $link_categories[ $id ] .= $category." "; $result = mysql_query("SElECT * FROM LINKS"); $link_categories = array(); while ($row = mysql_fetch_array($result,MYSQL_ASSOC)) { if (!isset($link_categories[$row['link']])) $link_categories[$row['link']] = " "; else $link_categories[$row['link']] .= " "; $link_categories[$row['link']] .= $row['category']; } print_r($link_categories); 

Результаты в:

 Array ( [http://a.com] => test evaluate performance [http://b.com] => classify reduce [http://c.com] => allocate ) 

Это не «правильный» способ сделать это – действительно, отношения должны быть определены в отдельной таблице с отношением 1-много.