我有以下查询,我通过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也将打印三次)。
我如何最好地解决这个问题?
这就是GROUP BY
的工作原理。
如果你想获得所有产品的所有图片,你可以(至少)用三种方法解决这个问题:
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: Use 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:使用聚合字符串函数获取产品的所有图像。这只在特殊情况下有效。这里,因为URL不能包含新行,例如
In 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;
In 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
}
}