简体   繁体   中英

SQL , how not to count 0 values

am trying to find a total vote using this code, I have 12 criteria; So am adding up the TOTAL for each SHOP_ID and then dividing by 12( the amount of columns used to make total). COUNT(shop_id) finds the number of shops, So for example if I have 2 shop_id inputs one with a total of 0 ( 12 entries of 0) and the other a total of 60 which is divided by the 12 criteria's then divided by shop_id count of 2 (60/12)/2 = 2.5 I would like the result to be 5. Some how not counting the column's with 0 in the division.

$sel = mysql_query("SELECT SUM(comfort + service + ambience + mood + spacious + 

    experience + cleanliness+ price + drinks + food + music + toilets)/(12/COUNT(shop_id) as total                  
    FROM ratings         
    WHERE shop_id = $shop_id");                 

if(mysql_num_rows($sel) > 0){
    while($data = mysql_fetch_assoc($sel)){
        $total = $total + $data['total']; 
        $rows++;
    }
    $perc = ($total/$rows);
    return round($perc,2);
} else {
    return '0';
}

Would it be better if i supply an image so visually display what am trying to achieve?

each row is NOT 1 vote, each shop_id is 12 votes. Each column category name: comfort + service + ambience, is a column id and an entry into that field is 1 vote, it counts the 12 as 1 vote, when if you vote for 1 criteria the other 11 are 0, and returns the wrong results, as division by 2 will half the correct answer

I have uploaded a visual example and shortened the rating columns from 12 to 7 for testing purposes. 表示例

try to use HAVING clause:

select
...
from
...
where
...
having COUNT(shop_id) > 0
SELECT SUM(comfort + service + ambience + mood + spacious + 
experience + cleanliness+ price + drinks + food + music + toilets)/(12/COUNT(shop_id) as total                  
FROM ratings         
WHERE shop_id = $shop_id
HAVING total > 0

I'm pretty sure your query is not quite right, but that could be a typo.

Here might be a better query:

SELECT shop_id, SUM(comfort + service + ambience + mood + spacious + 
experience + cleanliness+ price + drinks + food + music + toilets)/12 as total_rating                 
FROM ratings         
GROUP BY shop_id
HAVING total > 0

Personally, I think if someone is getting 0's across the board, that's worth noting, but the above should give you the average rating per shop and filter out any that are not at least 1.

If each category is from a scale of 0 - 5 and there are 12 categories, that means that their percent score is the (sum of the individual scores)/(possible total) * 100, or, in this case, the sum of the individual scores/.6 (works out the same way). If you want a "star rating" where the number of stars is equal to the top score of each category, that's just the average. In that case, I'd round off to one decimal. So if you want to go that route, here is the query I would use:

   SELECT shop_id, 
          Ceiling(
                 Sum(comfort + service + ambience + mood + spacious + 
                      experience + cleanliness + price + 
                      drinks + food + music + toilets
           ) /. 6) 
          AS  percent_rating, 
          ROUND(
            SUM(
              comfort + service + ambience + mood + 
              spacious + experience + cleanliness + 
              price + drinks + food + music + toilets
            )/12, 1)
          as star_rating
   FROM   ratings 
   GROUP  BY shop_id 

Now, if you want to have it laid out where each score is out of 100%, then it would be (cat_score/5) * 100 or (cat_score/.05). I'm not sure if there is an easy way to apply to that all of the categories without having to explicitly do the math for each field, but really I don't think you need to go to the trouble to figure out that 4/5 is 80%.

As far as what to do regarding a default 0 versus an intentional 0, you have no way of knowing the difference. If someone didn't feel moved enough to change it from a 0 (or a blank), it must not have been that terrific. Best bet is to set the default to the middle (3) and most folks will mark it lower if it was actually so bad it was a 0. Similarly, if you are giving the option of leaving it blank (which isn't 0, it's NULL), then you can either move it to 3 (which works out the same. If they left it all blank, that's the same as saying "so average I didn't fill it out) or you can make it some number you think is fair (1 or 2, maybe). Throwing it out is a pain mysql, and in statistics leads to misleading data (think hanging chad combined with language barrier so they left it blank). In the end, moving blank to the middle will be fine because you should have enough data when it's all said and done to get a standard deviation and other more valuable stats, rather than rely on plain averages (where a handful of bad reviews can throw off the whole curve).

添加到查询的末尾:

HAVING comfort + service + ambience + mood + spacious + experience + cleanliness+ price + drinks + food + music + toilets != 0

Your query is not quite right. It's missing a parenthesis.

Correct one:

$sel = mysql_query("SELECT SUM(comfort + service + ambience + mood + spacious +  
experience + cleanliness+ price + drinks + food + music +toilets)/(12/COUNT(shop_id)) 
as total FROM ratings WHERE shop_id = $shop_id having COUNT(shop_id) > 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