Domanda

I have those three very simple tables :

table user = 
[
    [
        'id'       => 1
        'username' => 'user1'
    ]
    [
        'id'       => 2
        'username' => 'user2'
    ]
    [
        'id'       => 3
        'username' => 'user3'
    ]
]

table cars = 
[
    [
        'id_user'  => 1
        'name'     => 'bmw'
    ]
    [
        'id_user'  => 1
        'name'     => 'audi'
    ]
    [
        'id_user'  => 1
        'name'     => 'honda'
    ]
    [
        'id_user'  => 2
        'name'     => 'dodge'
    ]
]

table bikes = 
[
    [
        'id_user'  => 1
        'name'     => 'yamaha'
    ]
    [
        'id_user'  => 1
        'name'     => 'suzuki'
    ]
    [
        'id_user'  => 3
        'name'     => 'kawasaki'
    ]
]

And I would like to load a user by his id with only one request and get the results like that :

exemple with id = 1 :

array result = 
[
    'id'         => 1
    'username'   => 'user1'
    'cars_name'  => 'bmw##audi##honda'
    'bikes_name' => 'yamaha##suzuki'
]

exemple with id = 2 :

array result = 
[
    'id'         => 2
    'username'   => 'user2'
    'cars_name'  => 'dodge'
    'bikes_name' => ''
]

I have tried this request :

'
    SELECT 
        user.id,
        user.username,
        GROUP_CONCAT(cars.name SEPARATOR "##"),
        GROUP_CONCAT(bikes.name SEPARATOR "##")
    FROM 
        user
    LEFT JOIN 
        cars ON user.id = cars.id_user
    LEFT JOIN
        bikes ON user.id = bikes.id_user
    WHERE
        user.id = $id
    LIMIT 1
'

But this outputs (exemple with id = 1) :

array result = 
[
    'id'         => 1
    'username'   => 'user1'
    'cars_name'  => 'bmw##audi#honda##bmw##audi#honda'
    'bikes_name' => 'yamaha##yamaha##yamaha##suzuki##suzuki##suzuki'
]

However it works fine with id = 2 and id = 3 :

(id = 2)

array result = 
[
    'id'         => 2
    'username'   => 'user2'
    'cars_name'  => 'dodge'
    'bikes_name' => ''
]

(id = 3)

array result = 
[
    'id'         => 1
    'username'   => 'user3'
    'cars_name'  => ''
    'bikes_name' => 'kawasaki'
]

How can i fix this ?

Thx for any help !

È stato utile?

Soluzione

The two LEFT JOIN are multiplying your results, giving you 6 results for user 1 (3 cars x 2 bikes).

You can use DISTINCT in GROUP_CONCAT to fix the duplicates.

From the docs:

GROUP_CONCAT([DISTINCT] expr [,expr ...]

         [ORDER BY {unsigned_integer | col_name | expr}
             [ASC | DESC] [,col_name ...]]
         [SEPARATOR str_val])

It would look like this:

SELECT 
  user.id,
  user.username,
  GROUP_CONCAT(DISTINCT cars.name SEPARATOR "##") AS cars,
  GROUP_CONCAT(DISTINCT bikes.name SEPARATOR "##") AS bikes
FROM user 
LEFT JOIN cars ON user.id = cars.id_user
LEFT JOIN bikes ON user.id = bikes.id_user
GROUP BY user.id
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top