Calculating the mean rating for each shop with MySQL

I am trying to combine the shop table with the rating table in order to fetch a list of all shops along with their individual ratings. However, my current query only returns shops that have ratings in the rating table. I want to display a rating of 0 for shops that do not have any ratings, and the actual rating for those that do.

shop table:-

id  shop name      
  1     shop_1      
  2     shop_2      
  3     shop_3      
  4     shop_4

rating table

id  shop_id  rating      
  1     1      3      
  2     4      2

Query:

$this->db->select('shop.*,shop.id as shop_id');
    $this->db->select('COALESCE(ROUND(AVG(rat.rating),1),0) as avgRate');
    $this->db->from('shop');
    $this->db->join('rating_reviews as rat', 'rat.shop=shop.id', 'left');
    $this->db->get()->result_array();

current output:

  id  shop_id      avgRate       
   1     1            3      
   2     4            2 

Expected output:

 id  shop_id      avgRate     
   1     1            3     
   2     2            0           //(no rating given for this shop)    
   3     3            0           //(no rating given for this shop)       
   4     4            2 

Answer №1

Here is a different method that eliminates the need for using JOIN:

select
  distinct shop_id,
  (
     select coalesce(round(avg(rating), 1), 0)
     from ratings where shop.id=ratings.shop_id
  ) as average_rating
from shops

Answer №2

Understanding Aggregate Functions

If you're encountering an error, it might be because functions like AVG and COUNT are considered as aggregate functions, meaning they consolidate all the data and usually produce a single result.

For instance:

  • Imagine there's a table named shops with id as its Primary Key
  • The table contains 35 shops
  • The Primary Key has no gaps (ranging from 1 to 35)

In such cases, the following queries will yield only one row/result:

# Query                          # Output:  # FIELD_1 # FIELD_2 (second statement)
SELECT COUNT(shop.id) FROM shop             # 35
SELECT shop.id, COUNT(shop.id) FROM shop    # 1       # 35

Both aforementioned queries would generate just one result. The first query counts the number of shops (35), while the second one also displays the ID of the first shop (1).

Your specific query operates on the same principle; similar to COUNT, the AVG function is an aggregate function that produces a singular result from the query.

SELECT 
    shop.*, shop.id as shop_id,
    COALESCE(ROUND(AVG(rat.rating),1),0) as avgRate
FROM shop
    LEFT JOIN rating_reviews AS rat ON rat.shop=shop.id

-- Result: All fields from `shop` for the first shop followed by [shop_id] and [avgRate]
-- For instance...
# shop.id # shop.name # shop.type   # shop_id # avgRate
# 1       # Tesco     # Supermarket # 1       # 3.5

Nevertheless, there are two methods to bypass this behavior:

Using GROUP BY

SELECT i, AVG(...) AS a FROM ... LEFT JOIN ... GROUP BY i

Utilizing Nested SELECT statements

SELECT i, (SELECT AVG(...) FROM ... WHERE ...) AS a FROM ...

GROUP BY Clause

SELECT 
    shop.*, shop.id as shop_id,
    COALESCE(ROUND(AVG(rat.rating),1),0) as avgRate
FROM shop
    LEFT JOIN rating_reviews AS rat ON rat.shop=shop.id
GROUP BY shop.id

Nested SELECT Statements

SELECT
    shop.*, shop.id as shop_id,
    (SELECT
         COALESCE(ROUND(AVG(rat.rating),1),0)
     FROM rating_reviews as rat
     WHERE rat.shop=shop.id
    ) as avgRate
FROM shop

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible for the client to see the PHP output within this JQuery script?

I have a page where users can contact me through a form. I want the message to be sent to an email address that my client can easily update. To achieve this, I've added a custom field (ACF) which is accessed using the following code: <?php the_fie ...

Using multi-dimensional JSON arrays for posting requests through Ajax

Is it possible to serialize HTML fields in a multi-dimensional array format for AJAX post transmission? I tried using serializeArray but it only formats the first level of the array. The data I need to serialize includes name/value pairs like: name="cus ...

PHP regular expression to extract names of cities from a given string

Seeking assistance in creating a regular expression in PHP to extract city names from a lengthy string. The basic pseudocode is as follows: if ( "v" or "V" or "vo" or "Vo" or "pri" or "Pri" or "od" or "Od" ...

retrieve PHP function calls as an array using Ajax

While working in PHP, I have encountered a situation where I needed to call a PHP function using AJAX: <button onclick="loop()">Do It</button> function loop() { $.get("ajax.php", { action: "true" }, function(result) { $("in ...

Refresh the Dom following an Ajax request (issue with .on input not functioning)

I have multiple text inputs that are generated dynamically via a MySQL query. On the bottom of my page, I have some Javascript code that needed to be triggered using window.load instead of document.ready because the latter was not functioning properly. & ...

Assistance requested for utilizing stripos() and substr() functions

Is there a way to remove everything before the word "sentido" in this given string? $string = "#BLitz da #PM na est do pontal sentido prainha perto do camping"; The desired new string is: $string = "prainha perto do camping"; I have tried using stripos ...

Dynamic number of parameters in Laravel routes

I'm attempting to develop a route that includes a mandatory parameter followed by an indefinite number of parameters. The exact count of additional parameters is uncertain, but it will always be more than zero. <?php Route::get('{tree_slug}/{ ...

Problem: Values are not being posted with AJAX when using $(form).serialize()

I'm encountering an issue with submitting a form using AJAX. I initially tried to pass the data using $("#myForm").serialize(), but for some reason, the receiving page doesn't receive the data. Take a look at my form: <form id="myForm"> ...

Unable to obtain Eventbrite API access token using a straightforward request

For some reason, my code that works perfectly fine with the Linkedin and Meetup APIs is failing with the Eventbrite API and I can't figure out why: $params = array( 'grant_type' => 'authorization_code', ...

Discover the executed SQL queries in Laravel

I'm struggling to store executed SQL queries in my $logs array. Unfortunately, despite using the DB::listen function, my $logs array remains empty. $logs = []; \DB::listen(function ($query) use ($logs) { print_r($query->sql); // The print ...

Issue with JSON parsing where quotes are missing around the name field

Is it feasible to decode JSON data when the names are not enclosed in double quotes? The JSON provided by Google appears like this: {e:"Data",b:"Data",f:"Data"} I am unable to notify Google about the incorrect format of their JSON, as it may be intention ...

Using CURL to connect to my personal network at home

Hey there, I have set up my home computer to run an Apache server on port 5900 with a Dynamic DNS to keep track of the IP address. I can access my server's index page from a different network using MYURL.com:5900. Now, I want to send a message to my h ...

I want to utilize a select drop-down menu for navigating between pages in my pagination, breaking away from the traditional method of using <a> tags

I have a select dropdown that is dynamically generated for navigation to other pages within the script. It lists the number of pages available for navigation. However, after selecting a page and loading it, the dropdown does not stay selected. I've tr ...

Unable to add information using the REST API

I attempted to utilize a REST API in CodeIgniter for inserting data. Here's the code snippet I used: public function sensor_post(){ $data = array( 'sensor_id' => $this->input->post('sensor_id'), ...

What is the process for a server to manage numerous users concurrently?

I can't help but wonder how servers manage multiple user requests for PHP scripts. Specifically, if a user opens a page that calls a PHP script using an ajax request and the script has a long processing time, what happens when more users access the sa ...

Transforming COLDFUSION into a powerful tool for encoding a WebServices API HASH instead of PHP code

I'm currently developing a ColdFusion website that requires communication with another system via Webservices. However, I am facing difficulties replicating a SHA512 based hash function in ColdFusion, despite having a sample code in PHP for reference. ...

Retrieving information from a database using PHP PDO to populate a dropdown list

On my HTML page, I have a form that allows users to insert data into the database. Some fields in the form require dropdown lists, and I want to populate these dropdowns with data from the database. Previously, I had hardcoded the dropdown options like th ...

Upgrading outdated pagination mysql_query PHP code to PDO

Currently in the process of transitioning to PDO for database management, I have implemented a news section on my website. The database connection is located within the header of the site. While using the following code for pagination, I am struggling to ...

Eliminate PHP method for removing JSON object name based on index

I put in a lot of effort to ensure that my title makes sense haha. Here is the JSON that I have: [{ "0": { "id": 130427, "created_at": 1512521776301, "updated_at": 1512549188911, "category": 0, "platform": 6, ...

The behavior of the Google chart seems quite unusual

I have this Google chart that retrieves data from a database. Here is what it looks like: https://i.stack.imgur.com/iuKJb.png Notice how a line is dragged across all the data, and it gets worse as you go further. Here is the code I am using: <!DOCTY ...