PHP и вывод результатов «один ко многим»
-
23-08-2019 - |
Вопрос
До сих пор я имел дело только с отношениями один-к-одному в 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, результат выглядит точно так же, как показано выше.Это здорово, но мне нужно, чтобы это читалось что-то вроде:
link_id = 4 url = 'http://www.somesite2.com' category = 'travel fun misc'
Таким образом, в основном все категории для каждого URL-адреса каким-то образом объединяются при их распечатке.Моя первая попытка заставила меня попробовать вложенный цикл while, но он не сработал, и я не уверен, осуществимо ли это.Кроме того, мне интересно, может ли мне понадобиться многомерный массив (полное предположение, мне никогда раньше не приходилось его использовать).
Я упорядочиваю эти результаты по идентификатору ссылки, как указано выше, поэтому я знаю, соответствует ли идентификатор ссылки в текущей итерации цикла идентификатору в последней итерации - тогда у меня есть что-то, что имеет более одной категории.Я думаю, что я очень близок к этому, но я просто не могу этого понять.
Есть идеи?
Решение
В MySQL также есть функция GROUP_CONCAT.Это должно сделать именно то, чего вы хотите достичь.
Что-то вроде :
SELECT url, GROUP_CONCAT(category) AS categories FROM yourtable GROUP BY url
Другие советы
Вам следует использовать таблицу соединений.
Во-первых, у вас есть таблица ссылок
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
Я использовал «отображение html» как общее «рабочее» событие, вы можете перенести его в структуру массива и т. д.вместо...
используйте массив с ключами по идентификатору и 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 -м.