简体   繁体   中英

PHP MySQL query multiple products in multiple categories

I want to output like this from the database:

Store name 1
--------------------
Product 1
Product 2

Store name 2
---------------------
Product 3
Product 4

and the query i use right now looks like this:

$query_stores = DB::query("SELECT * FROM `stores` LIMIT 16");

foreach($query_stores as $row){

   echo $row['name'] . '<br>';

   $query_products = DB::query("SELECT `id`, `name` FROM `products` WHERE `vendor` = %i ORDER BY RAND() LIMIT 10" , $row['id']);

   foreach($query_products as $row2){
      echo $row2['name'] . '<br>';
   }
}

The code works (sort of) but i can't filter the stores that don't have any items in the products table.

Example output:

Store name 1

Store name 2
    --------------------
    Product 1
    Product 2

Store name 3

Store name 4
    ---------------------
    Product 3
    Product 4

Store name 5

Is there a better way to run the code? Can the two queries be combined?

How to exclude the stores from output that don't have any items in the products table?

You're better off using a single query with a join statement and build an array of data to parse and display:

$sql = "SELECT s.id as store_id, s.name as store_name, p.id as product_id, p.name as product_name
            FROM stores s 
            LEFT JOIN products p ON (s.id = p.vendor)
            WHERE p.id IS NOT NULL
            ORDER BY s.name ASC, p.name ASC
            LIMIT 16";
$data = DB::query($sql);

After the query is run, $data will only contain stores that have products. The LEFT JOIN will make sure stores are the base information and if they have no products the product columns will be NULL . The WHERE clause makes sure that you filter out any stores with no products.

Setting up a structured array will make it easier to loop through your data.

$stores = []; // or if PHP version < 5.4 array();
foreach($data as $row) {
    if (!array_key_exists($row['store_id'], $stores)) {
        $stores[$row['store_id']] = [
            'store_name' => $row['store_name'],
            'products' => [],
        ];
    }

    $stores[$row['store_id']]['products'][$row['product_id']] = $row['product_name'];
}

And for outputting:

foreach ($stores as $store_id => $store) {
    echo $store['name'] .'<br/>';
    foreach ($store['products'] as $product_id => $product_name) {
        echo $product_name .'<br/>';
    }
}

Try something like this to reorder your queries so you can check if store is empty and then print if is not and if is empty then dont print it.

$query_stores = DB::query("SELECT * FROM `stores` LIMIT 16");

foreach($query_stores as $row){
    // put $query_products in front of echoing  and check if store is empty

    $query_products = DB::query("SELECT `id`, `name` FROM `products` WHERE `vendor` = %i ORDER BY RAND() LIMIT 10" , $row['id']);
    // Here you check if result is empty
    if(mysql_num_rows($query_products) > 0){
        echo $row['name'] . '<br>';   

        foreach($query_products as $row2){
            echo $row2['name'] . '<br>';
        }
    }
}

You could use mysql_num_rows(); function and check if number of result is < 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM