How would I go about running a PDO query and then processing the results with PHP to output an Average rating for a specific blank based on user inputted reviews?
Each review is weighted on 2 criterias, Service and Price. Both of this are 0-5 therefore the end average is weighted out of 10. Per review bases I currently use the following code to calculate the Average Rating for the specific review.
$rating_total = $row['review_service_rating'] + $row['review_price_rating'];
$average_rating = ($rating_total / 100) * 100;
So for each review there are 2 sql rows for review_service_rating and review_price_rating both of this are out of 5.
However I'm not exactly sure how to Count all of the ratings and then determine base grade for the specific page out of 10.
So let's say we have 3 reviews. This reviews are 7/10, 8/10 and 10/10. Logically we would add up all of the numbers and then add up all of /10 giving us. 25/30 which translates to 83.33 or in my case 8/10. This are the 2 steps I'm uncertain how to do.
1 - Get all ratings from SQL and count them
2 - Determine Average /10 based on all ratings
Current PDO code to pull data from DB as well as Count of how many Reviews each particular user has.
$q = $db->prepare("SELECT * FROM reviews WHERE assigned_id = :review_id ORDER BY review_posted DESC");
$q->execute(array(':review_id' => $_GET['page_id']));
$r = $q->fetchAll(PDO::FETCH_ASSOC);
echo '<br><div class="well">Average Rating</div><br>';
foreach($r as $row) {
$q = $db->prepare("SELECT * FROM users WHERE user_id = :review_user_id");
$q->execute(array(':review_user_id' => $row['user_id']));
$r = $q->fetch(PDO::FETCH_ASSOC);
$q = $db->prepare("SELECT COUNT(*) FROM reviews WHERE user_id = :review_user_id");
$q->execute(array(':review_user_id' => $row['user_id']));
$user_reviews = $q->fetchColumn();
Assume each user give x point (limit by 10), you must sum them up (x) then divide it by rating_times, you get average rating.
For example
User 1 rate 7
User 2 rate 6
User 1 rate 5
=> (7+6+5)/3 = 6
So you just add one more field when user rating called point.
Then use query SUM to SUM point up, divided with query COUNT then done.
forget the (x**/10**).
Finally, use 2 average rating (Price and service), sum of them, divided by 2 and you got overall rating.
Here's what you probably meant to do:
$q = $db->prepare("
SELECT *
FROM review r
JOIN users u ON r.user_id=u.id
JOIN (SELECT user_id, COUNT(1) as count FROM review GROUP BY user_id) uc ON uc.user_id = u.id
WHERE r.assigned_id=:review_id
ORDER BY r.review_posted DESC");
$q->execute(array(':review_id' => $_GET['page_id']));
$r = $q->fetchAll(PDO::FETCH_ASSOC);
foreach ($r as $row) {
// $row should have all fields included in $tables review and users as well as $row[count] would contain the total number of reviews a user made
}
This will include the user's details alongside the rating details for each review with that assigned_id
Edit: Added sum of user reviews as well.
You can use this snippet.
This helped me
https://gist.github.com/tiagofrancafernandes/1c5752ba2ebeb477975c6c016a37fc5c
Related
I've 4 table for a newsletter. Newsletters, Subscribers, Subscriber Groups and Selected Subscriber Groups. I've choose subscriber groups in campaign edit area, and its save selected groups to tbl_newsletter_groups table like;
tbl_newsletters
NID title details
1 text 1 content 1
2 text 2 content 2
tbl_subscriber_groups
GID group_name
5 group 1
6 group 2
tbl_subscribers
SID GID email name
10 5 sub1#mail.com sub1 name
11 6 sub1#mail.com sub1 name
tbl_newsletter_groups
NGID NID GID
15 1 6
16 1 6
17 1 6
I want to show total selected subscriber count when I list newsletters in my page. My soulution works fine, Im looking for simple and clearly statement, there any faster way available like in single newsletter list statement?
Here my own count style (yes I know its too bad and long way);
$subGID = array();
$list = $myconn->query("SELECT * FROM tbl_newsletters");
while($listRs = $list->fetch_assoc()){
$grps = $myconn->query("SELECT * FROM tbl_newsletter_groups WHERE NID=". $listRs['NID'] ."");
while($grpsRs = $grps->fetch_asscoc()){
$subGID[] = $grpsRs['GID'];
} $grps->free();
$subs = implode(" OR GID=",$subGID);
$count = mysqli_num_rows($myconn->query("SELECT ID FROM tbl_subscribers WHERE GID=". $subs));
echo('Total Selected Subscriber: '.$count);
} $list->free();
Thanks.
The search term you want is "set-based logic".
Your thinking is sound: you need everything from tbl_newsletters, then you need to count results from tbl_subscribers, but in order to get those you need information from tbl_newsletter_groups.
In SQL, that's an indication you want a join. You've already discovered the conditions you need, you just don't know the syntax. A reference manual can help there.
Now you'll have a bunch of records, which you need to smash into a smaller number of records. You need aggregation functions and a GROUP BY clause.
So here's the final query:
SELECT n.NID, n.title, n.details, COUNT(s.SID)
FROM tbl_newsletters AS n
JOIN tbl_newsletter_groups AS g ON n.NID = g.NID
JOIN tbl_subscribers AS s ON g.GID = s.GID
GROUP BY n.NID
I have 500 tables, all containing records of dollar amounts in the field "sales".
The following gets me the total sales of green items per table:
$tabletotal = mysql_query("SELECT sum(sales) FROM databasename.$tablename
WHERE type = 'green' AND descr LIKE '%SOLD%' ");
$row = mysql_fetch_assoc($tabletotal);
$answer= $row['sum(sales)'];
So if a particular table has 4 green items and they were sold for $4, $6, $7, and $3, then the answer I get above is $20.
Now, what I don't know how to do, is to get the total of all green items in ALL 500 tables. So if table 1 has a total of $20, table 2 a total of $36, table 3 a total of $15, and so on, I want to get the grand total in all tables together (in this case $71 but it would be more for 500 tables obviously).
Any help anyone?
Probably best to use a for loop:
$tables = array('tbl1', 'tbl2', 'tbl3', ..., 'tbl499');
$total = 0;
foreach ($tables as $t)
{
$tabletotal = mysql_query("SELECT sum(sales) tot FROM databasename.$t WHERE type = 'green' AND descr LIKE '%SOLD%'");
$row = mysql_fetch_assoc($tabletotal);
$total += $row['tot'];
}
Alternatively, you could generate a giant SQL query using UNIONs, but it's essentially the same thing.
As Dream Eater mentions; you shouldn't be in this situation in the first place.
I am writing a script for a car show. Users choose the car number and vote 1-5 on various criteria. There are multiple users voting for the same car, but they can only vote once for each car, I check for this.
Now I have a table of a unique carNumber and 1-5 votes for each criteria, per car.
Here is how I find the total score for each individual users vote
SELECT carNum, exterior+interior+engine AS Score FROM Judge_Votes WHERE catagory = '$catNum' ORDER BY carNum
Reults
CarNum: Score:
18 11
14 8
13 15
12 8
12 11
2 14
I want to add up the total score from each user into a final score result. IE car 12 has 19 total score.
The question I have. How can I find the total score using sql or php?
Just use SUM and ORDER BY:
SELECT carNum, SUM(exterior+interior+engine) AS Score
FROM Judge_Votes
WHERE catagory = '$catNum'
GROUP BY carNum
That should do the "trick"
SELECT carNum, sum(exterior + interior + engine) as Score
FROM Judge_Votes
WHERE gatagory = '$catNum'
GROUP BY carNum
ORDER BY carNum
The following should do the trick I think. The logic is that you group your result per car (GROUP BY carNum) and then use the build in SUM function of SQL.
SELECT SUM(exterior+interior+engine) as totalScore, carNum
FROM Judge_Votes
WHERE catagory = '$catNum'
GROUP BY carNum
ORDER BY carNum;
I've tried everything to figure this out but I can't get the correct total. My attempts either add all the records and not just the latest ones or I only get the first record.
My first table: hubs
hubID hubName
1 hub1
2 hub2
My second table: hub_reports
reportID hubID date health school
1 1 2012-04-27 467 322
2 2 2012-04-23 267 22
3 1 2012-01-20 176 623
So what you see is 2 tables, one with the organizations name and other info and the second with the reports that each organization submits quarterly. I want to list all the organizations and their latest report. At the bottom of the table I want to add all the available health kits and school kits that are currently available.
Here's the code I'm using right now to display all the organizations and their latest reports.
SELECT * FROM (SELECT hubName, date, health, school FROM hub_reports,
hubs WHERE hub_reports.hubID = hubs.hubID ORDER BY date DESC) AS Total
GROUP BY hubName
This seems to work but when I try the same tactic to get the SUM of the health and school columns I don't get the right answer.
SELECT SUM(health) FROM (SELECT hubName, date, health FROM
hub_reports, hubs WHERE hub_reports.hubID = hubs.hubID ORDER BY date
DESC) AS Total GROUP BY hubName
I tried other using a LEFT JOIN approach that I found on another forum but it didn't seem to work any better. But I maybe I wasn't doing it right.
Please help!
I just encountered a similar problem in a project of mine. A variation of this query worked for me. Hope it is helpful to you.
SELECT hubs.hubName, hub_reports.*,
SUM(hub_reports.health) AS ttl_health,
SUM(hub_reports.school) AS ttl_school
FROM hubs, hub_reports
WHERE hub_reports.hubID = hubs.hubID
GROUP BY hub_reports.hubID
ORDER BY hub_reports.date DESC
Here's the PHP:
$rs = mysql_query( 'SELECT hubs.hubName, hub_reports.*,
SUM(hub_reports.health) AS ttl_health,
SUM(hub_reports.school) AS ttl_school
FROM hubs, hub_reports
WHERE hub_reports.hubID = hubs.hubID
GROUP BY hub_reports.hubID
ORDER BY hub_reports.date DESC' );
$grand_total['school']=0;
$grand_total['health']=0;
while ( $row = mysql_fetch_assoc( $rs ) ){ // Step through each hub
echo "{$row['hubName']} shows {$row['ttl_school']} total school, {$row['ttl_health']} total health";
$grand_total['school'] += $row['ttl_school'];
$grand_total['health'] += $row['ttl_health'];
}
echo "Grand Total School: {$grand_total['school']}, Grand Total Health: {$grand_total['health']}";
You're likely looking for the MAX() function.
Try this:
SELECT h.hubID, h.hubname, MAX(hr.date) as hrdate, SUM(hr.health) as health, SUM(hr.school) as school
FROM hubs h
LEFT JOIN hub_reports hr ON hr.hubID = h.hubID
GROUP BY h.hubID
Edit
You want the MAX date so it only returns the most recent entry (assuming your entries are entered by date, of course).
This is the books table on db;
book_ID writer_ID
-------- -----------
1 10
2 10
3 10
4 10
5 10
This is the rates table on the db,
book_ID rate
------- --------
1 4
2 3
2 5
2 1
2 4
3 5
4 2
4 5
4 2
4 4
5 3
now, i have the writer_ID at first, and i have to find all book_ID (connected to that writer_ID) and the average rates of each book_ID from the rates table. finally, i have to find the greatest rate average and its book_ID
this is my code
$query="SELECT * FROM books WHERE seller_id ='$id'";
$result = mysql_query($query);
while ($info = mysql_fetch_array($result)) {
//getaveragerate is the function that returns average of the rates from rates table
$arr = array(ID => $info['book_ID'], average => getaveragerate($info['book_ID']));
}
$greatest_average_and_books_id_number = max($arr); // dont know how to get highest average and its ID together from array
that is my question, sorry but english is not my native language, i am trying my best to explain my problem. sometimes i cant and i just stuck.
thanks for understanding.
Or just let the database do it for you:
SELECT max(fieldname) FROM rates WHERE id='34'
If you are limited as to which functions you can perform (ie using some CRUD class):
SELECT * FROM rates WHERE id='34' ORDER BY id DESC LIMIT 1
You haven't told us what fields from the database will be returned by your query. It also looks like you're filtering (WHERE clause) on key column, which should only return one record. Therefore you can strip out everything you have there and only put:
$greatest_record = 34;
No need for a query at all!
With a little more information on what you're doing and what fields you're expecting:
$query = "SELECT id, rate FROM rates";
$result = mysql_query($query);
$myarray = array();
$greatest_number = 0;
while ($row = mysql_fetch_array($result)) {
myarray[] = $row; // Append the row returned into myarray
if ($row['id'] > $greatest_number) $greatest_number= $row['id'];
}
// Print out all the id's and rates
foreach ($myarray as $row_num => $row) {
print "Row: $row_num - ID: {$row['id']}, Rate: {$row['rate']} <br>";
}
print "Highest ID: $greatest_number";
Note that we maintained what was the greatest number at each row returned from the database, so we didn't have to loop through the $myarray again. Minor optimization that could be a huge optimization if you have tens of thousands of rows or more.
This solution is on the basis that you actually need to use the ID and RATE fields from the database later on, but want to know what the largest ID is now. Anyone, feel free to edit my answer if you think there's a better way of getting the greatest_number from the $myarray after it's generated.
Update:
You're going to need several queries to accomplish your task then.
The first will give you the average rate per book:
SELECT
book_id,
avg(rate) as average_rate
FROM Rates
GROUP BY book_id
The second will give you the max average rate:
SELECT
max(averages.average_rate),
averages.book_id
FROM (
SELECT
book_id,
avg(rate) as average_rate
FROM Rates
GROUP BY book_id
)
as averages
WHERE averages.average_rate = max(averages.average_rate)
This will give you a list of books for a given writer:
SELECT book_id
FROM Books
WHERE writer_id = $some_id
Don't try to do everything in one query. Mixing all those requirements into one query will not work how you want it to, unless you don't mind many very near duplicate rows.
I hope you can use this update to answer the question you have. These SQL queries will give you the information you need, but you'll still need to build your data structures in PHP if you need to use this data some how. I'm sure you can figure out how to do that.