Reputation: 556
I'm tackling my first project using PHP/MySQL in which I have a list of cities and ratings from 1-5 in certain categories (Food, Shopping, etc.). What I'm wanting to do is evaluate each row (each City), when a form is submitted on whether the categories are important or not.
This is how I want it to work.
Say, for example:
1. Chicago Food: 4, Shopping: 4, Nightlife: 4
2. New York Food: 4, Shopping: 5, Nightlife: 5
3. Boston Food: 5, Shopping: 4, Nightlife: 3
(the ratings are just for example)
And the user says that Food isn't important. Therefore the code will only evaluate Shopping and Nightlife... New York ends with 10, Chicago with 8 and Boston with 7.
As I have a list of around 35-40 cities that I want to evaluate on each category (if the user deems it "important") dynamically, and the winner will be the highest number at the end of the evaluation.
Does anyone have any ideas on how to go about this? I have the table built in MySQL with all the ratings, just need to write the code out now.
What I've tried: bringing in all of the values using arrays, but I've found it difficult to loop through each of the rows... help!
Upvotes: 2
Views: 405
Reputation: 22783
Assuming database tables similar to this (at least, they should be normalized in this fashion):
city ( id, name );
category ( id, name );
rating ( city_id, category_id, rating );
... with an array of interests similar to this:
$interests = array(
'Food',
'Shopping'
);
... the following sql:
$sql = 'SELECT
city.name as city,
GROUP_CONCAT( category.name || ": " || rating.rating, ", " ) as ratings,
SUM( rating.rating ) as totalRating
FROM
rating
JOIN
city
ON city.id = rating.city_id
JOIN
category
ON category.id = rating.category_id
WHERE
category.name IN( ' . implode( ',', array_map( array( $db, 'quote' ), $interests ) ) . ' )
GROUP BY
city.name
ORDER BY
totalRating DESC';
(I assumed the use of PDO
, utilizing PDO::quote()
for escaping here, but substitute the callback array( $db, 'quote' )
with whatever quoting/escape mechanism your mysql library offers)
... will yield a result set similar to this (I've populated random rating data for my example):
array (
0 => array (
'name' => 'Chicago',
'ratings' => 'Food: 3, Shopping: 3',
'totalRating' => '6'
),
1 => array (
'name' => 'New York',
'ratings' => 'Food: 1, Shopping: 4',
'totalRating' => '5'
),
2 => array (
'name' => 'Seattle',
'ratings' => 'Food: 4, Shopping: 1',
'totalRating' => '5'
),
3 => array (
'name' => 'Los Angeles',
'ratings' => 'Food: 2, Shopping: 2',
'totalRating' => '4'
),
4 => array (
'name' => 'Boston',
'ratings' => 'Food: 1, Shopping: 2',
'totalRating' => '3'
),
5 => array (
'name' => 'San Francisco',
'ratings' => 'Food: 1, Shopping: 1',
'totalRating' => '2'
)
)
If you only need the first result, append LIMIT 1
to the sql query.
This should give you an idea of how to go about accomplishing what you want.
Above all: let MySQL do all the work (filtering, sorting) — not PHP.
Upvotes: 1
Reputation: 1147
You can accomplish this task with just a little bit of PHP code and an appropiate SQL statement.
Here is a possible solution:
$important_cat = $_POST['categories']; //which is an array
$sql = "SELECT city, sum(".implode(' + ',$important_cat).") AS cat
FROM tbl
ORDER BY cat DESC";
//query sql
Upvotes: 1