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.
Related
I have a table that looks like this
id | itemID | catID | Title
----------------------------------------------------------------------------
0 3 4 Hello
1 3 6 Hello
2 4 4 Yo
3 4 8 Yo
4 5 2 Hi
5 1 3 What
I want to do a MySQL PHP Select that only gets one occurrence of the itemID. As you can see they are the same item, just in different categories.
This is what I tried
SELECT * FROM Table GROUP BY itemID
That didn't seem to work, it still just shows duplicates.
Is this what you are looking for? http://www.sqlfiddle.com/#!2/5ba87/1
select itemID, Title from test group by itemID;
As far as MySQL is concerned, the data is all unique, since you want all of the columns. You have to be more specific.
Do you just want the itemID (or other column)? Then say so:
select [column] from Table GROUP BY itemID
Do you want the last entry of a particular item ID? Then say that:
select * from Table where itemID = 1 ORDER BY id DESC
Or the first one?
select * from Table where itemID = 1 ORDER BY id
If none of these are what you want, then you probably need to restructure your tables. It looks like you want different categories for your items. If so, then you'll want to split them out into a new join table, because you have a many-to-many relationship between Items and Categories. I recommend reading up on database normalization, so you're not duplicating data (such as you are with the titles).
If you want everything for the distinct itemIDs, you could certainly take a long route by doing one selection of all of the distinct itemIDs, then doing a series of selections based on the first query's results.
select distinct(`itemID`) from Table
Then in your PHP code, do something like this:
while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$itemID = $row['itemID'];
$sql2 ="SELECT * FROM Table WHERE 1 and `itemID`=\"$itemID\" limit 1";
$result2 = #mysql_query($sql2, $connection);
while ($row2 = mysql_fetch_array($result2))
{
$id = $row2['id'];
$itemID = $row2['itemID'];
$catID = $row2['catID'];
$Title = $row2['Title'];
}
}
This is what my customers_basket table looks like:
customers_id | products_id | basket_quantity
3 | 56:3121fefbe6043d6fc12e3b3de2c8fc38 | 3
3 | 56:fb4c9278fcfe6225b58c06711a7e62ef | 1
3 | 56:8e334fce09556108f5416e27154b6c27 | 1
3 | 52:f3b9f38e4ddd18035bc04cd264b0f052 | 1
This is the query I'm using:
$products_in_cart_query = "SELECT products_id FROM customers_basket WHERE customers_id = " . $_SESSION['customer_id'] ."";
$products_in_cart = $db->Execute($products_in_cart_query);
$products_in_cart_model = $products_in_cart->fields['products_id'];
$products_in_cart_model = substr($products_in_cart_model, 0, strpos($products_in_cart_model, ":"));
The end result I get is 56,56,56,52
First of all, how do I use the first line's quantity field? I'd need to list that products_id 3 times since quantity is 3. Therefore, the end result needs to be: 56,56,56,56,56,52
or, for easier understanding (56,56,56),56,56,52
And second, how do I count how many same values I have? In this case, I have 5x56 and 1x52. I need to use those counts in my further calculation.
EDIT: further calculations explained
I need to know how many of each product_id I have and then run something like this:
foreach(product_id) {
$shipping_cost += FIXED_VALUE * basket_qty;
}
To get the basket quantity, you have to select it. It would be best if the first portion of the product ID was stored in a separate column, rather than having to do messy operations like substringing.
Query 1: 2-character codes and corresponding quantities
SELECT SUBSTR(products_id, 1, 2) AS product_code, basket_quantity
FROM Customers_Basket
WHERE customers_id = 3;
Query 2: 2-character codes and summed quantities
SELECT product_code, SUM(basket_quantity) AS total_quantity
FROM (SELECT SUBSTR(products_id, 1, 2) AS product_code, basket_quantity
FROM Customers_Basket
WHERE customers_id = 3
)
GROUP BY product_code;
If you really, really, really desperately want 3 rows of data for the product ID 56:3121fefbe6043d6fc12e3b3de2c8fc38, then you have to know ways to generate rows. They're truly painful in the absence of convenient SQL support (so much so, that you'd do better to select a row in PHP with the quantity and then generate the appropriate number of rows in your array in the client-side (PHP) code). I'm going to assume that some variation on these queries will get you the information you want.
I need i bit of help with this query, so far i have this:
SELECT * FROM coupons WHERE discount_id = '1' AND client_username = 'Zara' GROUP BY winner_id
The table is like this
id client_username winner_id bdate discount_id destroyed
72 zara 1125405534 2012-11-11 03:34:49 4 0
71 zara 1125405534 2012-11-11 03:34:43 1 0
70 zara 1125405534 2012-11-11 03:34:27 1 0
I want to group the result by winner_id (its a unique user id) where discount_id is equal to some value and order by bdate, the think is I need the id bdate and destroyed value of each ocurrence of the user and also count the number of times winner_id appear, so the result needs to be a value (count of how many times winner_id appears), and 3 arrays (discount_id,destroyed,id).. But I have no idea how to retrive this in the way I need. Thanks for any help!
Two basic methods:
aggregate in mysql and "explode" in php
aggregate in PHP
number 1 involves using some aggregate functions in your query, like COUNT() and GROUP_CONCAT():
SELECT count(*) as num_wins, GROUP_CONCAT(discount_id, ',') as discount_ids ...
then in PHP, these GROUP_CONCAT columns can be "exploded" into arrays while looping over the results:
foreach($rows as $row) {
$discount_ids = explode(',', $row['discount_ids']);
// ...
}
number 2 is easier SQL, but uglier PHP. Basically just select all your rows, and then pre-process the results yourself. (I recommend the previous solution)
foreach($rows as $row) {
$results_tree[$row['winner_id']]['num_wins']++;
$results_tree[$row['winner_id']]['discount_ids'][] = $row['discount_id'];
// ...
}
I have a database table. It contains the folowing columns:
Cathegory | Priority |
Is there a finished script or a way to display statistics for these columns?
Basically what I am trying to do is show statistics for these columns.
For example,
cathegory can have different values, as an example: (Continent,
Country, City, Street).
Priority can contain a value between 1-10.
So I would need to display how many rows there are, the and the different values for each row.
For example:
4 of the priority 8 rows have 'continent' as catheogry,
43 of the priority 8 rows have 'country' as cathegory,
329 of the priority 8 rows have 'city' as cathegory
Is this possible?
There are no built-in scripts that can do that for you but certainly you get all that kind of information using SQL, that's the basic idea of a relational database.
Number of rows in table
select count(*) from table;
The example
select cathegory, count(cathegory) nbr_of_cathegories_for_prio_8 from table where priority = 8 group by cathegory;
In you example : 329 of the priority 8 rows have 'city' as cathegory
I assume that:
8 - is the priority value.
329 - how many time the priority is repeated for that specific priority for a specific category.
the PHP implimentation will look something like:
<?php
$sql = "
SELECT Priority, COUNT(Priority) as nbr_of_Priorities, cathegory,
FROM table_Name
GROUP BY Priority, cathegory
";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
{
echo $row['nbr_of_Priorities'].'of the priority'.$row[' Priority'];
echo 'has'.$row['cathegory'].'as catheogry';
}
?>
I've created a game with a highscore table in MySQL.
I have a "My scores" button that needs to retrieve the users scores, e.g.:
10. John 395
42. John 340
90. John 10
How should I go out retrieving the rank (10th, 42th, 90th) of each score of the user?
I could pull all the scores from the database and iterate through them but that doesn't seem like a good solution.
Let me try to expand:
I retrieve all MY scores from the database. E.g. 10 scores. I want to display these 10 scores however I won't know what the rank of these scores is compared to the other scores in my database! (10th, 16th, etc) ..Hope that makes more sense...
Thanks
For the position in the total list you either need to build up a list every time you want this overview, or use a stored procedure to build a list for a given moment. You could 'cache' a list on a given interval. Or maybe update a list when some one played a game that would change the top 100.
As #WhiteElephant suggested, you'd be making the table every time you want the data.
#stefandoorn suggest to not use the optimized count of sql, i think this is not efficient enough for these kind of computations.
A simple SQL query would do it for you. For example, if you want the 10th score, you could use:
SELECT name, score FROM highscores ORDER BY score DESC LIMIT 1 OFFSET 9
The offset will always be the position required - 1.
If you want to have the associated rank as a column beside the score, you could do the following:
SELECT #rownum:=#rownum+1 position, name, score FROM (SELECT #rownum:=0) r, highscores ORDER BY score DESC
This doesn't work with an offset (the position number will always start at 1). The result would be something like the following:
+----------+-------------+-------+
| position | name | score |
+----------+-------------+-------+
| 1 | Player 1 | 27681 |
| 2 | Player 2 | 14982 |
+----------+-------------+-------+
But I think the best solution is to just loop through the returned values with an index and use the index to keep track of the position.
SELECT
id, name, score,(select count(*) FROM highscores AS higherscores WHERE higherscores.score>currentscores.score)+1 AS rank
FROM
highscores AS currentscores
WHERE name="john"
;
Just use ORDER BYscoreDESC in the end of your query to sort them in reversed order (from high to low). When iterating and showing it in PHP you can use a count:
Query e.g.: SELECT * FROM scores ORDER BY score DESC
$count = 1;
$sql = 'SELECT * FROM scores ORDER BY score DESC';
$result = mysql_query($sql) or die(mysql_error());
while($fetch = mysql_fetch_object($result)) {
echo $count . ' ' . $fetch->score . '<br />';
$count++;
}