1

I'm working on a PHP / MySQL classified search engine where people can type some keywords and the results page should :

1) List the users who published listings matching these keywords

AND

2) Below these user's names, list these listings that match these keywords

I'd like to achieve this with only one MySQL query but I'm not sure if it's even possible.

Actually, I'm able to get the list of users with this query :

SELECT u.id, u.firstname 
FROM user u 
WHERE 
u.id 
IN (SELECT user_id FROM product WHERE make LIKE '%Porsche%')

Now I'm wondering how to also get the list of products within the same query. If it's not possible in one query, what would be the most optimized method?

1
  • you also need to give details about products. how is the database designed. Commented May 23, 2019 at 9:00

3 Answers 3

3

Something like this:

SELECT u.id, u.firstname, p.* 
  FROM user u 
  INNER JOIN product p 
  ON u.id=p.user_id
WHERE p.make LIKE '%Porsche%';
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! But there is one flaw : for example, if I want the query to return only 10 users, how can I do that since the number of results is based on the number of products and not the number of users who published these products?
There are a few ways to do so. 1) you can use ORDER BY u.id DESC/ASC LIMIT 10: this will return 10 id but according to your order by, whether its DESC=descending or ASC=ascending. 2) You can define the user based on id and add into your WHERE; for example if id is running like 1 to 10, you can add WHERE u.id BETWEEN 1 AND 10 or if scattered id you can add WHERE u.id IN (1,2,5,6,9,....); 3) If the user id specific by u.firstname and order by u.id; WHERE u.firstname='john' ORDER BY u.id ASC LIMIT 10
1

I would do the work, in "reverse":

  1. Fetch all products matching title with matching user id and firstname.
  2. Sort results by user in PHP

Sometimes it's faster to do things what way rather than trying to ask too much to MySQL. MySQL is faster on simple query and PHP is good to sort datas as long as your logic is right.

Here is an exemple:

1 - Fetch data (MySQL):

SELECT p.*, u.id AS user_id, u.firstname AS user_firstname  
FROM `products` AS p 
INNER JOIN `user` AS u ON u.id = p.user_id 
WHERE p.make LIKE '%Porsche%' 
ORDER BY p.make, u.id

I don't know the full list of columns in you products table but it should produce something like this for each row:

id, make, user_id, user_firstname

2 - Sort results with PHP (assuming you use PDO, which I strongly recommand):

// Data will contain the sorted results
$data = array();
// This variable will be used to be sure results owning by a certain user are children of this user
$curent_index = null;
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
    // Assign index to row user id (if different from current)
    if($current_index != $row['user_id']) {
        $current_index = $row['user_ic'];
    }

    // Create entry matching the user (if doesn't exist)
    if(!array_key_exists($current_index, $data)) {
        $data[$current_index] = array(
            'firstname' =>  $row['firstname'],
            'products'  =>  array()
        );
    }

    // Add product in data user array

    $data[$current_id]['products'][$row['id']] = array(
        'make'  =>  $row['make'],
        // whatever other fields product have
    );

}

This should produce a result array like so :

1 =>    array(
    'firstname' =>  'Toto',
    'products'  =>  array(
        1   =>  array(
            'make'  =>  'My Porsche'
        ),
        2   =>  array(
            'make'  =>  'Porsche, an history of red cars'
        ),
        //...
    )
),
3   =>  array(
    'firstname' =>  'Titi',
    'products'  =>  array(
        7   =>  array(
            'make'  =>  'Porsche or Ferrari?'
        ),
        10  =>  array(
            'make'  =>  'Why Porsches are so expensive?'
        ),
        // ...
    )
)   

Comments

0

The query should be as

SELECT u.id, u.firstname, p.* 
  FROM user u 
  INNER JOIN product p 
  ON u.id=p.user_id
WHERE p.make LIKE '%Porsche%' LIMIT 10;

This will limit the first 10 result. And in your post you haven't asked anything about limiting.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.