MySQL — php SQL-запрос возвращает несколько строк для каждой отдельной записи, неправильное использование объединений?

Я пытаюсь, чтобы мой запрос возвращал каждую запись в моей базе данных один раз, проблема в том, что если в списке есть несколько изображений, хранящихся в отдельной таблице, он возвращает несколько записей (по одной для каждого изображения)

вот фрагмент моего макета базы данных (данные, завернутые в **, являются первичными ключами)

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, чтобы получить изображения?

Буду признателен за любую помощь
ура

0

Решение

Ты можешь использовать 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)Таким образом, вы все еще в безопасности, но если вам нужны не только имена файлов, но и другие свойства файла (тип, владелец?), вы застряли. В этом случае нет ничего постыдного в выполнении отдельного запроса для имен файлов или других деталей, которые встречаются несколько раз.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]