简体   繁体   中英

Echo all results from sql join when using group by

I have the following query which I run via PHP:

select 
    {$tableProducts}.*,
    {$tableImages}.*
from {$tableProducts}
left join {$tableImages}
    on {$tableImages}.product_id = {$tableProducts}.product_id
group by {$tableProducts}.product_id;

Each product (from product table) can have several images (in images table). I loop through the results with a simple while statement:

while($row = $results->fetch_object()) {
    echo $row->product_name; // Product table
    echo $row->image_src; // Image table
}

Problem: Only the first image of each product is printed, but I want to display all of them. All images are printed if I remove the "order by" part, but then the product_name is printed once for each image (so if one product has three images, the product_name would be printed three times as well).

How do I best solve this?

That's how GROUP BY works.

If you want to get all images for all products, you can solve that (at least) 3 ways:

1 : Do not use GROUP BY , handle it in the loop, like:

$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 & query all images with different statements within the loop.

$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 : Use aggregate string functions to get all images for a product. This is only works in special cases, f.ex. here, as URL cannot consist new lines, for example.

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;

In the loop:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM