【问题标题】:php sql query returns multiple rows for each individual record, misuse of joins?php sql查询为每条记录返回多行,滥用连接?
【发布时间】:2014-11-19 13:54:30
【问题描述】:

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

这是我的数据库布局的sn-p(**包裹的数据是主键)

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(expr) MySQL 分组函数。抱歉,您的 SQL 有点长,无法用一个我可以确定它是正确的示例来编写答案。还有其他人吗?
  • @kiko软件,谢谢你的回复我去看看。

标签: php mysql sql join group-by


【解决方案1】:

您可以使用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) 解决,因此您仍然是安全的,但是如果您不仅想要文件名,还想要文件的其他属性(类型、所有者?),您就会被卡住。在这种情况下,对多次出现的文件名或其他详细信息运行单独的查询并不可耻。

【讨论】:

  • 感谢您抽出宝贵时间详细讨论此问题,我明天会检查并告诉您我的进展情况,感谢您的帮助
  • 这真是一种享受!非常感谢您的帮助。希望最大长度不会成为问题,因为我一次只会在我的页面上显示 25 个列表,所以即使每个列表有 10 个图像,它也不会是大量数据。手指交叉:)
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 1970-01-01
  • 2021-03-13
  • 2012-05-05
  • 2012-08-25
  • 2017-01-02
相关资源
最近更新 更多