How can I get the average of the values in three columns? - mysql

I have this table named rating:
id | helpful | necesary | lenght
1 | 3 | 1 | 5
1 | 4 | 3 | 2
2 | 5 | 3 | 5
3 | 3 | 3 | 5
1 | 1 | 2 | 3
3 | 2 | 3 | 2
This table stores the rating a user gives to anarticle from 1 to 5....How can I query the top 5 id that has the highest rating having averaged the 3 colums helpful, necesary, length?
AVG gives me the average for a column and LIMIT well gives me the top 5, but I can't get a start on how to average three columns.

Maybe you want to do this:
SELECT id FROM (
SELECT id, (helpful + necesary + legnth) / 3 average
FROM rating ORDER BY average DESC
) t
LIMIT 5;

The simplest way is just to add the values from the columns and divide them by the number of columns.
SELECT (helpful + necesary + length) / 3 AS "avg" FROM rating ORDER BY avg DESC LIMIT 5;

You can sum the values manually, sort by that sum, and then divide the sum by the number of columns to get the average:
select id, helpful, necesary, lenght,
((helpful + necesary + lenght) / 3) as avg
from rating
order by (helpful + necesary + lenght) desc
limit 5

Related

select average from average

I have the following table:
rating
--------
| id | account_id | room | kitchen | bathroom |
-----------------------------------------------
| 1 | 1 | 5 | 5 | 5 |
| 2 | 1 | 2 | 4 | 1 |
| 3 | 1 | 5 | 2 | 1 |
-----------------------------------------------
People can rate the room, kitchen and bathroom (from 1-5).
Average rating for ID = 1: 5 (because 15/3 = 5)
Average rating for ID = 2: 2.3333 (because 7/3 = 2.33333)
Average rating for ID = 3: 2.6666 (because 8/3 = 2.66665)
First question
As you can see, the average rating for ID = 2 => 2.3333... and for ID = 3 => 2.6666. How can I make it floor() and ceil()? (when < .5 => floor, when > .5 => ceil), so that the avg rating for ID = 2 becomes 2 (instead of 2.3333) and the avg rating for ID = 3 becomes 3 (instead of 2.6666...)
Second question
I want to select the average rating of the average ratings (so the average rating from all the rows together). So - when floor() and ceil() are used I have 3 average ratings: 5, 2 and 3 => 10/15 => 3. How do I get to the 3?
Thanks in advance!
For the first question, the answer is round():
select round( (room + kitchen + bathroom) / 3)
For the second, you would just use aggregation:
select avg(room + kitchen + bathroom)
from ratings;
If you want the average of the rounded results:
select round(avg(round(room + kitchen + bathroom)))
from ratings;
However, that seems strange to me.
Use ROUND function.
Query
SELECT id, ROUND(((room + kitchen + bathroom)/3), 0) as `average`
FROM rating
GROUP BY id;

groupby get the average length name

I'm using the group by function to get some products from my little shop like:
select name, ProductID from blog group by ProductID
+----------------------------------------------------------+
| name |
+----------------------------------------------------------+
| AAA |
| BBBB |
| CCCC |
| DDDDDDDD |
+----------------------------------------------------------+
Is it possible to get the average length name in the groupby function?
EDIT (from OP, placed in answer):
myysql> select length(name) as len, name from product where article=40 order by len asc;
+------+----------------------------------------------------------+
| len | name |
+------+----------------------------------------------------------+
| 3 | aaa |
| 6 | BBBBBB |
| 6 | CCCCCC |
| 8 | dddddddd |
+------+----------------------------------------------------------+
4 rows in set (0.00 sec)
by this example I need to get one value like BBBBBB or CCCCCC (AVG?)
Your example doesn't get the average length name, because there is no such thing. The average length would be (8 + 3 + 6 + 6) / 4 = 5.75. It doesn't exist. I think you want the median, which is the size such that 50% are bigger and 50% are smaller.
Here is one way to get the median (assuming that names don't contain commas and that the concatenation doesn't exceed certain limits):
select ProductID,
substring_index(substring_index(group_concat(name order by length(name) separator '||'
), '||', 1 + count(*)/2
), '||', -1) as MedianLengthName
from blog
group by ProductID;
Try this query:
SELECT AVG(CHAR_LENGTH(name)) AS avg FROM tbl;
If you are looking for an the mean average (which implies you would have to accept the integer above and below that decimal value), you can use this:
SELECT *
FROM (
SELECT AVG(CHAR_LENGTH(name)) AS average
FROM product) AS calculated
JOIN product
ON CHAR_LENGTH(name) BETWEEN FLOOR(average) AND CEILING(average);

Order by after element

Is there a way to do a query that orders by a field after a certain element id. I am trying to implement pagination based on the last returned element, and want to be able to both order elements a property and return the next paged based on the last element of the previous page.
For example a user may ask for 25 elements after element with id = 10 sorted on cost.
Imagine you have:
id | name | price
1 | Fish | 5
2 | Burger | 2
3 | Veggies | 6
If we want to get after id=2 sorted by price it should return
2 | Burger | 2
1 | Fish | 5
3 | Veggies | 6
If we want to get after id=1 sorted by price it should return
1 | Fish | 5
3 | Veggies | 6
You can do:
SELECT *
FROM YOURTABLE
WHERE id >= 10
ORDER BY cost ASC
LIMIT 25;
EDIT:
According to your new information, you can do that with:
SELECT *
FROM YOURTABLE
WHERE price >= (SELECT price from Table1 WHERE id = 2)
ORDER BY price ASC
LIMIT 25;
sql fiddle demo

Select a Sum the last 5 rows

I'm building a little quiz game in PHP/MySQL. After asking questions I want a screen to display how many of the last round were answered correctly.
Im storing whether they were answered correctly or not in a table that looks like this:
rowID | questionid | playerid | answercorrect |
1 | 1 | 1 | 1 |
2 | 2 | 1 | 1 |
3 | 3 | 1 | 1 |
4 | 4 | 1 | 1 |
5 | 5 | 1 | 0 |
6 | 6 | 1 | 1 |
7 | 7 | 1 | 1 |
I want to see how many of the last x (usually 5) questions were answered correctly.
I thought this would be simple. I'm trying this:
SELECT sum( answercorrect ) FROM `answersgiven` ORDER BY id DESC LIMIT 5
I thought this would sum the answercorrect column for the last 5 rows, giving me an answer of 4, but it's giving me 7, which is the result for ALL of the rows.
I feel like I'm missing something obvious. It seems like a simple thing to want to do.
Any ideas?
Try this:
SELECT sum(answercorrect)
FROM (SELECT answercorrect FROM `answersgiven` ORDER BY rowID DESC LIMIT 5) t1
Example Fiddle
In your query, the LIMIT clause affects the overall result: So first all are summed up (which results in one row - the sum over all rows) and then the first 5, if available, are taken (which again is just the one row).
The easiest way of achieving your target is to first select just the first 5 rows (in the subselect) and then sum up afterwards.
try this query
SELECT sum(col)
FROM (SELECT col FROM `table` ORDER BY id DESC LIMIT 5) t1
You're almost there. Just sum up those top 5 answers now:
SELECT SUM('top5')
FROM
(SELECT answercorrect AS 'top5'
FROM `answersgiven`
ORDER BY id DESC LIMIT 5) 'x'

Averaging an average in mySQL

I have a table
car
id | person_id | mpg
------------------------
4 | 1 | 50
5 | 1 | 15
6 | 2 | 10
7 | 2 | 28
8 | 3 | 33
I need to get an average of each person's mpg and then an average for the group.
person 1 avg = (50 + 15) / 2 = 32.5
person 2 avg = (10 + 28) / 2 = 19
person 3 avg = 33
group average = 32.5 + 19 + 33 / 3 = 28.1
Is there a query that will do what I need?
SELECT person_id, AVG(mpg) from car group by person_id;
If you want to get an average for the group, you should probably do this:
SELECT AVG(mpg) from car;
Unless you really want to average the averages, which seems a bit dubious to me:
SELECT AVG(average) from (SELECT person_id, AVG(mpg) as average from car group by person_id);
you cannot solve this in 1 query, but you have to use 2 queries or 1 query en solve the overal average in your code
select person, avg(mpg) from cat group by person
SELECT person_id, AVG(mpg) AS mpg_avg FROM car GROUP BY person_id WITH ROLLUP
The WITH ROLLUP-modifier will add a line to the result set where persion_id is NULL and mpg_avg is the average over the whole result set (MySQL >= 4.1.1):
person_id | mpg
------------------
1 | 32.5
2 | 19.0
3 | 33.0
NULL | 27.2