I have a table named cars. Then I have a table named car_infos and then I have a table car_photos.
So if I have 3 images on my car_photos and want to select all cars then my rows shows the car x3. If I have 4 images then my rows shows the car x4. So if I have 2 cars in my table and I select all cars then it shows 8 times. 4 for each image. If I group it by ID then it shows correctly but how can I put my images that the car have in a array ?
query:
<?php
session_start();
require_once __DIR__ . '/../config/db.php';
$handy = array();
$handy['records'] = array();
$data = json_decode(file_get_contents('php://input'), true);
if($stmt = $pdo->prepare("
SELECT
cars.id,
cars.name,
car_info.car_id,
car_info.bedingungen,
car_info.beschreibung,
car_info.price,
car_info.c_year,
car_info.mileage,
car_info.engine,
car_info.transmission,
car_info.ps,
car_info.max_kmh,
car_photos.car_id,
car_photos.image,
car_photos.added
FROM cars
LEFT JOIN car_info
ON car_info.car_id = cars.id
LEFT JOIN car_photos
ON car_photos.car_id = cars.id
GROUP BY `cars`.`id`
ORDER BY car_photos.added ASC LIMIT 100;")) {
if(!$stmt->execute()) {
print_r($stmt->errorInfo());
} else {
while($row = $stmt->fetch()) {
$handyList = array(
'id' => $row['id'],
'name' => $row['name'],
'bedingungen' => $row['bedingungen'],
'beschreibung' => $row['beschreibung'],
'price' => $row['price'],
'c_year' => $row['c_year'],
'mileage' => $row['mileage'],
'engine' => $row['engine'],
'transmission' => $row['transmission'],
'ps' => $row['ps'],
'max_kmh' => $row['max_kmh'],
'image' => $row['image'],
);
array_push($handy['records'], $handyList);
}
http_response_code(200);
echo json_encode($handy);
}
}
?>
So if I group it then it shows correclty but I only get one photo result not the others... I want to have a car with all the images that the car have. But with group it shows only one photo.
CodePudding user response:
For newer versions you can use JSON_ARRAYAGG()
to group related photos to one column. You would need a query like this:
SELECT
cars.*, -- list all required columns in the final code
car_info.*, -- list all required columns in the final code
JSON_ARRAYAGG(JSON_OBJECT(
'image', car_photos.image,
'added', car_photos.added
)) as photos
FROM cars
LEFT JOIN car_info
ON car_info.car_id = cars.id
LEFT JOIN car_photos
ON car_photos.car_id = cars.id
GROUP BY cars.id
ORDER BY cars.id ASC LIMIT 100;
However, since your version (MariaDB 10.4) doesn't support JSON_ARRAYAGG()
you should use GROUP_CONCAT()
and CONCAT()
as workaround. Change the SELECT part to
SELECT
cars.*,
car_info.*,
CONCAT('[', GROUP_CONCAT(JSON_OBJECT(
'image', car_photos.image,
'added', car_photos.added
) ORDER BY car_photos.added ASC), ']') as photos
It might even be prefered because GROUP_CONCAT
supports sorting, while JSON_ARRAYAGG
does not.
Then decode that JSON value in PHP:
Change
'image' => $row['image'],
to
'photos' => json_decode($row['photos'], true),
You will get a nested array and can access the images with something like
$handy['records'][5]['photos'][2]['image']
which would be the 3rd image from the 6th car (considering 0-indexing).