Я пытаюсь, чтобы мой запрос возвращал каждую запись в моей базе данных один раз, проблема в том, что если в списке есть несколько изображений, хранящихся в отдельной таблице, он возвращает несколько записей (по одной для каждого изображения)
вот фрагмент моего макета базы данных (данные, завернутые в **, являются первичными ключами)
tbl_listings => **listingID**,title,description,dateListed
tbl_images => **imageID**,filename
tbl_listing_image => **listingID**,**imageID**
это мой код
$stmt = $db->stmt_init();
if($stmt->prepare("SELECT l.listingID, l.title, l.description, l.dateListed, c.category, tn.townID, tn.town, i.filename
FROM tbl_listings AS l
LEFT JOIN tbl_listing_category AS lc ON lc.listingID = l.listingID
LEFT JOIN tbl_category AS c ON c.categoryID = lc.categoryID
LEFT JOIN tbl_listing_type AS lt ON lt.listingID = l.listingID
LEFT JOIN tbl_type AS t ON t.typeID = lt.typeID
LEFT JOIN tbl_listing_town AS ltn ON ltn.listingID = l.listingID
LEFT JOIN tbl_towns AS tn ON tn.townID = ltn.townID
LEFT JOIN tbl_listing_image AS li ON li.listingID = l.listingID
LEFT JOIN tbl_images AS i ON i.imageID = li.imageID
WHERE t.typeID =?"))
{
$type = 1;
$stmt->bind_param("i",$type);
$stmt->execute();
$stmt->bind_result($id,$title,$desc,$date,$cat,$townID,$town,$image);
echo "<ul>";
while($stmt->fetch())
{
$img = "images/listing/$id/$image";
echo "<li><img src='$img' alt='$title' title='$title'>#".$id."<h4>" . $title . "</h4>" . $desc . "<br /><strong> Category:</strong> " . $cat . " - <strong>Location: </strong> - <strong> Posted On:</strong> " . date("i M Y",$date) . "</li><hr>";
}
echo "</ul>";
$stmt->close();
который возвращает следующие результаты (учитывая, что в таблице tbl_listings есть только 1 запись)
listingID title description dateListed category townID town filename
1 listing 1 listing desc 1411240751 teaching 11 town a image1.jpg
1 listing 1 listing desc 1411240751 teaching 11 town a image2.jpg
1 listing 1 listing desc 1411240751 teaching 11 town a image3.jpg
таким образом, запрос возвращает 3 записи (по одной на каждое имя файла), хотя его список совпадает
поэтому я попытался добавить GROUP BY l.listingID к моему запросу, который возвратил только одну запись, но он также вернул только первое изображение, вот так
listingID title description dateListed category townID town filename
1 listing 1 listing desc 1411240751 teaching 11 town a image1.jpg
так что мой вопрос для каждого списка, как я могу вернуть только 1 запись, но все связанные с ней изображения? мне нужно выполнить отдельный запрос в цикле while, чтобы получить изображения?
Буду признателен за любую помощь
ура
Ты можешь использовать GROUP_CONCAT
чтобы перечислить имена файлов как одно поле:
SELECT l.listingID, l.title, l.description, l.dateListed, c.category, tn.townID, tn.town,
GROUP_CONCAT(i.filename) as filenames
FROM tbl_listings AS l
LEFT JOIN tbl_listing_category AS lc ON lc.listingID = l.listingID
LEFT JOIN tbl_category AS c ON c.categoryID = lc.categoryID
LEFT JOIN tbl_listing_type AS lt ON lt.listingID = l.listingID
LEFT JOIN tbl_type AS t ON t.typeID = lt.typeID
LEFT JOIN tbl_listing_town AS ltn ON ltn.listingID = l.listingID
LEFT JOIN tbl_towns AS tn ON tn.townID = ltn.townID
LEFT JOIN tbl_listing_image AS li ON li.listingID = l.listingID
LEFT JOIN tbl_images AS i ON i.imageID = li.imageID
WHERE t.typeID =?
GROUP BY l.listingID
Преимущество состоит в том, что у вас есть один запрос с одним временем туда-обратно, так что это довольно эффективно. Конечно, вам нужно снова разделить эти имена, но в PHP это тривиально.
С другой стороны, есть максимальная длина GROUP_CONCAT
может вернуться, и если в категории может быть много файлов, вы можете достичь этого предела.
Кроме того, если любая из других таблиц также вызывает дублирование, вы можете получить каждое имя файла несколько раз. Это может быть решено с помощью GROUP_CONCAT(DISTINCT filename)
Таким образом, вы все еще в безопасности, но если вам нужны не только имена файлов, но и другие свойства файла (тип, владелец?), вы застряли. В этом случае нет ничего постыдного в выполнении отдельного запроса для имен файлов или других деталей, которые встречаются несколько раз.
Других решений пока нет …