I’ve two tables, one being the Customer table and the other the Address table having a one to many between them. I want to select all customers with their respective addresses and displaying it something like this:
{
id: 222,
name: John Doe,
age: 32,
addresses: [
{ id: 1, address: "some address", customer_id: 222 },
{ id: 2, address: "secondary address", customer_id: 222}
]
}
My code is the following now:
$sql = "SELECT * FROM customers JOIN addresses ON customers.id = addresses.customer_id";
$result = $connection->query($sql);
$rows = array();
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
print json_encode($rows);
But it results in two records with same data but different address property. How could I achieve the upper example?
Sample data:
customers table:
id | name | age 222 | John | 32
addresses table:
id | customer_id | address 1 | 222 | Some address 2 | 222 | Secondary address
Current result:
[
{
id: 222,
name: John,
age: 32,
address: Some address
customer_id: 222
},
{
id: 222,
name: John,
age: 32,
address: Secondary address
customer_id: 222
}
]
SQL scripts:
CREATE TABLE `customers` ( `id` bigint(20) NOT NULL, `name` varchar(50) NOT NULL, `age` int(11) NOT NULL, ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `addresses` ( `id` bigint(20) NOT NULL, `address` varchar(150) NOT NULL, `customer_id` bigint(20) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `customers` ADD PRIMARY KEY (`id`); ALTER TABLE `customers` MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2; ALTER TABLE `addresses` ADD PRIMARY KEY (`id`), ADD KEY `customer_id` (`customer_id`); ALTER TABLE `addresses` MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; ALTER TABLE `addresses` ADD CONSTRAINT `addresses_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; COMMIT; INSERT INTO `customers` (`id`, `name`, `age`) VALUES (1, 'John', 32); INSERT INTO `addresses` (`id`, `address`, `customer_id`) VALUES (1, 'Some address', 1), (2, 'Secondary address', 1);
Advertisement
Answer
If you need to solve the issue on DB side you can use JSON_ARRAYAGG function in you query:
SELECT
`customers`.`id`,
`customers`.`name`,
`customers`.`age`,
JSON_ARRAYAGG(`addresses`.`address`) AS `addresses`
FROM `customers`
JOIN `addresses` ON `customers`.`id` = `addresses`.`customer_id`
Here You can test this query and PHP code
The PHP solution can be next:
<?php
$sql = "SELECT
`customers`.`id`,
`customers`.`name`,
`customers`.`age`,
`addresses`.`address`
FROM `customers`
JOIN `addresses` ON `customers`.`id` = `addresses`.`customer_id`
";
$result = $mysqli->query($sql);
$rows = array();
while ($row = $result->fetch_assoc()) {
if (is_array($rows[$row['id']])) {
array_push($rows[$row['id']]['address'],$row['address']);
} else {
$rows[$row['id']] = $row;
$rows[$row['id']]['address'] = (array)$rows[$row['id']]['address'];
}
}
var_export($rows);