使用group by时,回显sql join的所有结果

时间:2013-05-16 12:21:04

标签: php sql group-by while-loop left-join

我有以下查询,我通过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也会打印三次)。

我如何才能最好地解决这个问题?

1 个答案:

答案 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
    }
}