我试图让我的查询返回我的数据库中的每条记录一次,问题是如果列表中有多个图像存储在一个单独的表中,它会返回多个记录(每个图像一个)
这是我的数据库布局的片段(包裹在**中的数据是主键)
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 :(得分:2)
您可以使用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)
来解决,因此您仍然可以安全,但如果您不仅需要文件名,还需要文件的其他属性(类型,所有者?),那么您就会陷入困境。在这种情况下,对于多次出现的文件名或其他详细信息运行单独的查询没有任何耻辱。