Selecting max of sum of rows - php

I have a table in the database like this:
student_id | subject_id | get_ca1 | get_ca2 | get_exam
----------------------------------------------------------
101 | 1 | 10 | 7 | 10
102 | 2 | 5 | 5 | 10
103 | 1 | 9 | 10 | 4
101 | 1 | 8 | 10 | 10
103 | 2 | 2 | 10 | 10
104 | 1 | 7 | 8 | 5
101 | 2 | 7 | 8 | 5
I want to get the highest score of a student in a subject. But first, I would have to sum up the rows get_ca1 + get_ca2....+ get_exam to another column to get the total scores of each student in a particular subject.
Then I want to get the Max score from the total. This means;
the highest score in subject_id = 1 is 28 gotten by student_id=101
the highest score in subject_id = 2 is 22 by student_id = 103
So far, this is my query:
SELECT MAX(`get_ca1`+`get_ca2`+`get_exam`)
AS max_score
FROM exam_results WHERE `subject_id`=1
This outputs 28.
Now, this is how I want my table in view to look:
For student_id= 103
subject | ca1 | ca2 | exam | highest
----------------------------------------
Maths | 9 | 10 | 4 | 28
Eng | 2 | 10 | 10 | 22
This is where my problem lies. I tried putting the code directly in the view file like this:
<td>
<?php
$query = $this->db->query("SELECT MAX(`get_ca1`+`get_ca2`+`get_exam`)
AS max_score FROM exam_results WHERE `subjects.id`=1");
$highscore = $query->row();
echo $highscore->max_score;
?>
</td>
It outputs 28 correctly. However, it shows 28 in all the subjects. I'm guessing is because of this WHERE `subjects.id`=1"
If I'm to go by this method, how do I get the highest scores to show in each subject column?
is it WHERE `subjects.id`=.'"$subject_id"`"?
But I would prefer the MVC method which I'm not so familiar with.
so far...
Model
public function GetMaxScore($subject_id)
{
$this->db->select_max('`get_ca1`+`get_ca2`+`get_exam` AS max_score');
$this->db->where('subject_id', $subject_id);
return $this->db->get('max_score')->row();
}
Controller:
public function GetMaxScore($subject_id)
{
$data = $this->examgroupstudent_model->GetMaxScore($subject_id);
return $data->max_score;
}
If this is correct by any means, how do I output it in my view?

Related

PHP - Count distinct rows where two other columns are distinct

I'm trying to output the number of distinct results from a row where two other tables factor into the equation, but I'm not sure how to make this work. Here's what I have. I have counted the total times which a word appears in the database.
$total = "SELECT word, count(word) total FROM Table WHERE Word = 'Apples'";
total = 9. Ok, good. That was easy.
+-------------+--------------+--------------+--------------+
| BookID (INT)| chapter (INT)| page (INT) | word (VCHAR) |
+-------------+--------------+--------------+--------------+
| 40 | 1 | 8 | Apples |
| 40 | 1 | 8 | Apples |
| 40 | 1 | 15 | Apples |
| 40 | 4 | 23 | Apples |
| 50 | 3 | 15 | Apples |
| 50 | 6 | 15 | Apples |
| 51 | 13 | 1 | Apples |
| 52 | 2 | 3 | Apples |
| 60 | 8 | 1 | Apples |
+-------------------------------------------+--------------+
Now, here's where I'm needing some assistance. I want to find the number of times the word is used on a DISTINCT page in each chapter of each book. So, based on the table above, I am expecting the total to be 8. I'm close with this code, but I can't find the next step.
$pages = "SELECT COUNT(DISTINCT page) AS num FROM Table WHERE word = 'Apples' GROUP BY BookID, chapter, page";
This gives me:
1
1
1
1
1
1
1
1
So, I'm getting the correct number. 8 rows. Now I just need to add those up and output them as a single number. 8. I've looked into SUM, but that doesn't seem to work (if I'm mistaken, please show me how I should include it.)
You may simply take the sum of your current query as a subquery:
SELECT SUM(num) AS total
FROM
(
SELECT COUNT(DISTINCT page) AS num
FROM yourTable
WHERE word = 'Apples'
GROUP BY BookID, chapter, page
) t;

Finding inner join mysql with array [duplicate]

This question already has answers here:
How to join two tables using a comma-separated-list in the join field
(5 answers)
Closed 2 years ago.
I have two tables, First one is products where it has list of products with some specifications, in the other hand I have a table with clients and what type of product they want, they might want a product in any town of a list exactly as explained in the following tables,
Products Table like
| id | owner | userid | city | town | status | price |
| 1 | jon spee | 10 | 10 | 4 | 0 | 10500 |
| 2 | Hiss Roe | 10 | 7 | 9 | 0 | 20000 |
| 3 | John Smi | 10 | 10 | 12 | 0 | 10000 |
Clients Table like
| id | fullname | userid | city | towns | status | price |
| 1 | name 1 | 10 | 10 |4,8,6,2| 0 | 20000 |
| 2 | name 2 | 10 | 7 | 7,2,9 | 0 | 25000 |
| 3 | name 3 | 10 | 10 | 1 | 0 | 20000 |
MySQL Query :
SELECT *
FROM clients
INNER JOIN products
ON (
clients.userid = products.userid AND
clients.price >= products.price AND
clients.city = products.city AND
clients.status = products.status
I want it to check also in towns like for each town it executs this query (dynamically),
(products.town LIKE '%4%' OR products.town LIKE '%8%' OR products.town LIKE '%6%' OR products.town LIKE '%2%')
You could go with this query
SELECT *
FROM clients
INNER JOIN products
ON (
clients.userid = products.userid AND
clients.price >= products.price AND
clients.city = products.city AND
find_in_set(clients.town, products.town) AND
clients.status = products.status
you can also fetch it in php and create your statement based on the results fetched
Your primary effort should go into fixing your data model. Don't store multiple integer values in a string column. You should have a separate table to store the relation betwen clients and towns, which each tuple on a separate row.
That said: for your current design, you can join on find_in_set():
on
clients.userid = products.userid
and ...
and find_in_set(product.town, client.towns)

$this->db->group_by() and adding the quantity

I have this in my receipt UI(Note: This is only from one user):
Item_Name | Quantity | Price | Total
Panty | 2 | 50 | 100
Bra | 1 | 35 | 35
Panty | 2 | 50 | 100
As you can see the user gets the Panty TWICE!
I want my UI to be looking like this:
Item_Name | Quantity | Price | Total
Panty | 4 | 50 | 100
Bra | 1 | 35 | 35
As you can see the Panty's that the user buys groups together, but in my query instead of Panty having 4 Quantity it still has 2
Here is my Code:
public function getClientReservation($name){
$this->db->select('*');
$this->db->from('tbl_item_availed');
$this->db->join('tbl_items','tbl_items.Item_ID = tbl_item_availed.Item_ID');
$this->db->join('user_account','user_account.Account_no = tbl_item_availed.Account_no');
$this->db->where('Username',$name);
$this->db->where('isReserve',1);
$this->db->where('Active',1);
$this->db->group_by('tbl_items.Item_Name');
$query = $this->db->get();
return $query->result();
}
Please help!
This is the table tbl_item_availed by the way:
Item_availed_id | Item_ID | Quantity | Account_no
1 | 1 | 2 | 5
2 | 2 | 1 | 5
3 | 1 | 2 | 5
table tbl_items:
Item_ID | Price | Item_Name
1 | 100 | Panty
2 | 35 | Bra
table user_account:
Account_no | Firstname | Lastname
1 | LeBron | James
2 | Dwyane | Wade
3 | Wilt | Chamberlain
4 | Michael | Jordan
5 | Charles | Barkley
Try this.
public function getClientReservation($name){
$this->db->select('tbl_items.`Item_Name`, SUM(tbl_item_availed.`Quantity`) AS quantity, tbl_items.`Price`, (tbl_items.`Price`*(SUM(tbl_item_availed.`Quantity`))) AS total');
$this->db->from('tbl_item_availed');
$this->db->join('tbl_items','tbl_items.Item_ID = tbl_item_availed.Item_ID');
$this->db->join('user_account','user_account.Account_no = tbl_item_availed.Account_no');
$this->db->where('Username',$name);
$this->db->where('isReserve',1);
$this->db->where('Active',1);
//$this->db->group_by('tbl_items.Item_Name');//do not use this line unless item name is unique
//group by item id
$this->db->group_by('tbl_items.Item_ID');
$query = $this->db->get();
return $query->result();
}
Also use GROUP BY for Item_ID (assuming it is unique), not Item_Name unless it is unique.
Side note:
Moreover, use Account_no instead of username in WHERE clause. If you want to modify it, just replace this line
$this->db->where('Username',$name);
with
$this->db->where('Account_no',$account_no);

function SQL SUM query

I have a table with numbers like this:
______________________________________
| axle_id | train_id | axle | distance |
|_________|__________|______|__________|
| 1 | 1 | 1 | 20 |
| 2 | 1 | 2 | 50 |
| 3 | 1 | 3 | 200 |
| 4 | 1 | 4 | 50 |
| 5 | 1 | 5 | 200 |
| 6 | 1 | 6 | 50 |
| 7 | 1 | 7 | 200 |
| 8 | 1 | 8 | 50 |
|_________|__________|______|__________|
Now i want to count them and make a calculation with SUM.
The code i have right now:
function count_axles($id) {
$sql = "SELECT sum(distance)/(25000)*(100) as totaldistance from axle WHERE train_id = :train_id";
$sth = $this->pdo->prepare($sql);
$sth->bindParam(":train_id", $id, PDO::PARAM_STR);
$sth->execute();
return $sth->fetchAll();
}
And i call this function via:
<?php
$count_axle = $database->count_axles($_GET['train_id']);
?>
<?php
foreach($count_axle as $counting){
}
echo $counting['totaldistance'];
?>
Now the output is correct.
(3.2800000000000002) This is the percentage of 25.000
But i want to add 5000 like:
$sql = "SELECT sum(distance)+(5000)/(25000)*(100) as totaldistance from axle WHERE train_id = :train_id";
But when i do that, the output generates something randomly like:
840
Why does it do this, and how do i solve this?
Basic math. You're doing
5000
sum(distance) + --------------
25000 * 100
when you really want
sum(distance) + 5000
------------------------
25000 * 100
Try
SELECT (sum(distance)+(5000))/(25000)*(100)
^--------------------^
instead. Note the extra brackets.
And remember the old BEDMAS mnemonic: brackets, exponents, division, multiplication, addition, subtraction...
Try with:
$sql = "SELECT (sum(distance)+(5000))/(25000)*(100) as totaldistance from axle WHERE train_id = :train_id";
Division has preference over sum operations.

PHP stack multiple values into one value

This is the bookings table I'm using for my query
+----------------------+
| event_id | person_id |
+----------------------+
| 5 | 7 |
| 4 | 7 |
| 3 | 7 |
| 4 | 5 |
| 3 | 5 |
| 5 | 3 |
+----------------------+
This table shows that person_id 7 has 3 bookings, 5 has 2 bookings and 3 has 6 bookings.
Currently, I'm using this query to get the total number of bookings per person.
$query='
SELECT
bookings.person_id,
COUNT(bookings.person_id) AS total,
bookings.event_id,
users.display_name
FROM bookings
INNER JOIN users ON bookings.person_id=users.id
WHERE users.id=bookings.person_id
GROUP BY bookings.person_id';
$result = mysql_query($query);
if($result) {
while($row = mysql_fetch_array($result))
{
/* total bookings per user */
$value = $row['total'];
$sum += $value;
/* events booked per user */
$events....
/* Displaying results */
echo "<tr width='500'>";
echo "<td>".$row['person_id']."</td>";
echo "<td>".$row['display_name']."</td>";
echo "<td>".$row['total']."</td>";
echo "<td>".$events."</td>";
echo "</tr>";
}
This works okay and gives me:
+-----------------------------------+
| ID | NAME | Total Bookings |
+-----------------------------------+
| 7 | Bob | 3 |
| 5 | Jane | 2 |
| 3 | Joe | 1 |
+-----------------------------------+
I'm seeking help to get this to display the events booked by each person (like the 4th columns below):
+------------------------------------------------+
| ID | NAME | Total Bookings | Event IDs |
+------------------------------------------------+
| 7 | Bob | 3 | 5,4,3 |
| 5 | Jane | 2 | 4,3 |
| 3 | Joe | 1 | 5 |
+------------------------------------------------+
Could you please help me getting there.
Thanks.
GROUP_CONCAT https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
$query='
SELECT
bookings.person_id,
COUNT(bookings.person_id) AS total,
GROUP_CONCAT(bookings.event_id) as event_ids,
users.display_name
FROM bookings
INNER JOIN users ON bookings.person_id=users.id
WHERE users.id=bookings.person_id
GROUP BY bookings.person_id';
A bit different query but same result:
SELECT
bookings.person_id,
COUNT(
bookings.person_id
) AS total,
users.display_name,
GROUP_CONCAT(
bookings.event_id
ORDER BY
bookings.event_id
) AS events_list
FROM
bookings,
users
WHERE
bookings.person_id=users.id
GROUP BY
bookings.person_id
ORDER BY
bookings.person_id
I don't know if for a large data, the execution time is less, more or equal.

Categories