我有以下查询,我通过PHP运行:
select
{$tableProducts}.*,
{$tableImages}.*
from {$tableProducts}
left join {$tableImages}
on {$tableImages}.product_id = {$tableProducts}.product_id
group by {$tableProducts}.product_id;
每个产品(来自产品表)可以有多个图像(在图像表中)。我用一个简单的while语句遍历结果:
while($row = $results->fetch_object()) {
echo $row->product_name; // Product table
echo $row->image_src; // Image table
}
问题:仅打印每个产品的第一张图片,但我想显示所有这些图片。如果我删除“order by”部分,则打印所有图像,但随后为每个图像打印一次product_name(因此,如果一个产品有三个图像,则product_name也会打印三次)。
我如何才能最好地解决这个问题?
答案 0 :(得分:1)
这就是GROUP BY
的工作方式。
如果您想获得所有产品的所有图像,您可以解决(至少)3种方式:
1 :请勿使用GROUP BY
,请在循环中处理,例如:
$last_product = null;
while($row = $results->fetch_object()) {
if ($last_product !== $row->product_id) {
// new product starts here
$last_product = $row->product_id;
echo $row->product_name; // Product table
}
echo $row->image_src; // Image table
}
2 :使用GROUP BY
&在循环中查询具有不同语句的所有图像。
$products = <query products>;
while($row = $products->fetch_object()) {
echo $row->product_name; // Product table
$images = <query images for product in $row>;
while($row = $images->fetch_object()) {
echo $row->image_src; // Image table
}
}
3 :使用聚合字符串函数获取产品的所有图像。这仅适用于特殊情况,f.ex。这里,因为URL不能包含新行,例如。
在MySQL
:
select
{$tableProducts}.*,
group_concat({$tableImages}.image_src SEPARATOR '\n') as image_srcs
from {$tableProducts}
left join {$tableImages}
on {$tableImages}.product_id = {$tableProducts}.product_id
group by {$tableProducts}.product_id;
在PostgreSQL
:
select
{$tableProducts}.*,
string_agg({$tableImages}.image_src, '\n') as image_srcs
from {$tableProducts}
left join {$tableImages}
on {$tableImages}.product_id = {$tableProducts}.product_id
group by {$tableProducts}.product_id;
在循环中:
while($row = $products->fetch_object()) {
echo $row->product_name; // Product table
foreach (explode("\n", $row->image_srcs) as $image_src) {
echo $image_src; // Image table
}
}