Home » Php » php – SQL Select data from two tables, one row -> multiple rows

php – SQL Select data from two tables, one row -> multiple rows

Posted by: admin February 25, 2020 Leave a comment

Questions:

I have the following two tables:

customers:  |  phones:
--------------------------------------
id          |  id
name        |  owner (FK_CUSTOMERS)
address     |  number

I load a html table in laravel blade to show all the customers and I want a table cell with the phones saved for each customer.

So one customer may have no phones, just one or multiple phones. I need to retrieve each customer with their phones in one row, or there is a better way to do this?

If I do something like this results one row per phone with duplicate data:

 $customers = DB::table('customers')
        ->join("phones","customers.id", "=", "phones.owner")
        ->where("phones.group",1)
        ->select(
            'customers.id',            
            'customers.name',            
            'customers.fiscalNumber',            
            'customers.disscount',   
            'customers.billAddress',   
            'customers.tax',
            'phones.number'                   
        )
        ->get();

I want this:

id | name    | address          | phones
5  | Michael | fake address 123 | 666777888,111222333,444555666

I have tried several things but nothings works. Thanks

How to&Answers:

You should group your customers by id, and use group_concat to extract all phone numbers as a comma separated string. It should look something like this:

$customers = DB::table('customers')
    ->join("phones","customers.id", "=", "phones.owner")
    ->where("phones.group",1)
    ->select(
        'customers.id',
        'customers.name',
        'customers.fiscalNumber',
        'customers.disscount',
        'customers.billAddress',
        'customers.tax',
        DB::raw('group_concat(phones.number) as number')
    )
    ->groupBy('customers.id')
    ->get();

Answer:

Instead of joining your tables, which sometimes is an anti pattern using Eloquent. Use Eloquent mutators to solve your problem.

Define the relationship to phones and a mutator.

class Customer {
    public function phones() {
        return $this->hasMany(Phone::class, 'owner');
    }

    public function getPhoneNumbersAttribute() {
        return implode(',', $this->phones->pluck('number')->all());
    }
}

To use you mutator simply fetch your model and access it. For performance optimisation, load phones with the with() method, that eager loads the relationship.

Customer::with('phones')->find(1)->phoneNumbers; // [666777888,111222333,444555666]