当使用groupby时,回显sql join的所有结果


Echo all results from sql join when using group by

我有以下查询,我通过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
    }
}