PHPSQL查询为每个记录返回多行,是否滥用联接?

PHPSQL查询为每个记录返回多行,是否滥用联接?,php,mysql,sql,join,group-by,Php,Mysql,Sql,Join,Group By,我试图让我的查询返回数据库中的每一条记录一次,问题是如果列表中有多个图像存储在一个单独的表中,它将返回多条记录(每个图像一条记录) 这是我的数据库布局的一个片段(包装在**中的数据是主键) 这是我的密码 $stmt = $db->stmt_init(); if($stmt->prepare("SELECT l.listingID, l.title, l.description, l.dateListed, c.category, tn.townID, tn.town, i.filen

我试图让我的查询返回数据库中的每一条记录一次,问题是如果列表中有多个图像存储在一个单独的表中,它将返回多条记录(每个图像一条记录)

这是我的数据库布局的一个片段(包装在**中的数据是主键)

这是我的密码

$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();
因此,查询返回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
因此,我的问题是,对于每个列表,我如何仅返回一条记录,但返回其所有关联图像?我是否需要在while循环中运行单独的查询来获取图像

非常感谢您的帮助
干杯

您可以使用
GROUP\u 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\u CONCAT(DISTINCT filename)
来解决,因此您仍然是安全的,但是如果您不仅需要文件名,还需要文件的其他属性(类型、所有者?),那么您就被卡住了。在这种情况下,对多次出现的文件名或其他详细信息运行单独的查询没有什么丢脸的。

请参阅GROUP_CONCAT(expr)MySQL分组函数。抱歉,您的SQL有点太长,无法用一个示例来编写答案,我可以肯定它是正确的。还有其他人吗?@kiko software,谢谢你的回复,我会查看的。谢谢你花时间详细讨论这件事,我明天会查看,让你知道我的进展,感谢你的帮助,这让我很开心!!非常感谢你的帮助。最大长度希望不会成为问题,因为我一次只能在我的页面上显示25个列表,所以即使每个列表都有10个图像,也不会有大量的数据。祈祷吧:)
listingID   title        description    dateListed    category    townID    town    filename
1           listing 1    listing desc   1411240751    teaching    11        town a  image1.jpg
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