SUM of columns while grouping by other column - php

So this is the structure of my MySQL table that I wanna work this out with:
ID type category_id amount
12 Expense 3 963.39
13 Expense 5 1200.50
14 Expense 3 444.12
15 Expense 5 1137.56
..............................
Desired output:
1407,41 (for category_id = 3)
2338,06 (for category_id = 5)
....... (and for other category_id)
What I get now:
1407,41 (only for category_id = 3)
My query does not add or display the sum of other category_id.
This is the query I am trying:
$query = "SELECT SUM(amount) AS TotalAmount FROM spendee WHERE type = 'Expense'
group by category_id having count(*) >1 ";
$expense_query = mysqli_query($connection, $query);
$expense_count = mysqli_fetch_array($expense_query);
echo $expense_count[0];
Been stuck with this for the last couple of days. Any help is very much appreciated. Thank you!

You're only calling mysqli_fetch_array() once. You need to call it in a loop to get all the totals. You should also include the category ID in the SELECT list.
$query = "SELECT category_id, SUM(amount) AS TotalAmount FROM spendee WHERE type = 'Expense'
group by category_id having count(*) >1 ";
$expense_query = mysqli_query($connection, $query);
while ($row = mysqli_fetch_assoc($expense_query)) {
echo "{$row['TotalAmount']} (for category_id = {$row['category_id']}<br>\n";
}

The query here works. It's just that you only select the first result from the $expense_count variable. $expense_count[1] will return the second category listed, $expense_count[2 will return the third one, ect...
Try echo implode(" <br>", $expense_count);
Have a nice day.

Related

Select from 2 tables not working with php mysql

I have two different tables of the following structure:
grouprel
id | userId | pupID | groupId
pupils
id | userId | fname | lname
pupId in groulrel is equal to id in pupils.
I want to fetch pupils from a different group and then order them by fname, lname.
Now I have two queries like this:
$q = "SELECT * FROM grouprel WHERE userid = ". $userid ." AND groupId = ". $_GET['id'] ."";
$r = mysqli_query($mysqli, $q);
while ($rows = mysqli_fetch_object($r)) {
$query = "SELECT id, fname, lname FROM pupils WHERE userid = ". $userid ." AND id = ". $rows->pupId ." AND status = 0 ORDER BY fname, lname";
$result = mysqli_query($mysqli, $query);
while($row = mysqli_fetch_object($result)) {
echo stuff...
}
}
This works, but it doesn't order the names alphabetically like I want to.
How could I fix this?
This is iterating over the first query:
while ($rows = mysqli_fetch_object($r)) {
And this iterates over each instance of the second query:
while($row = mysqli_fetch_object($result)) {
So if the first query returns 1,2,3, and each iteration of the second query returns A,B, then your output would be:
1 A
1 B
2 A
2 B
3 A
3 B
The second query is ordering by the ORDER BY clause you gave it. But you are ordering the entire output by the first query.
Ultimately, why do you need these separate queries at all? Executing a database query in a loop is almost always the wrong idea. It looks like all you need is one query with a simple JOIN. Guessing on your logic, something like this:
SELECT
pupils.id, pupils.fname, pupils.lname
FROM
pupils
INNER JOIN grouprel ON pupils.id = grouprel.pupId
WHERE
pupils.userid = ?
AND grouprel.groupId = ?
AND pupils.status = 0
ORDER BY
fname, lname
It may take a little tweaking to match exactly what you're looking for, but you can achieve your goal with a single query instead of multiple separate queries. Then the results of that query will be ordered the way you told MySQL to order them, instead of the way you told PHP to order them.

How can I show all data under specific category using sql query?

well, I have 2 Mysql table which structure is bellow :
Table Jobs
job_id---job_cat_id---job_title---job_description---job_data----is_active
=========================================================================
1 1 title 1 description 1 2016-05-06 1
2 2 title 2 description 2 2016-05-06 0
3 2 title 3 description 3 2016-05-06 1
Table job_details
job_cat_id---job_cat_name
=========================
1 cat name 1
2 cat name 2
3 cat name 3
Now I want to show all jobs under each category from jobs table. E.g
What I need to show :
Job Category 1
1. job 1 from category 1
2. Job 2 from category 1
Job Category 2
1. Job 3 from category 2
So to do this I am using following sql query but can't get the correct result :
$get_job = mysqli_query($conn, "SELECT jobs.job_id, jobs.job_title, job_category.job_cat_name FROM jobs LEFT JOIN job_category ON job_category.job_cat_id = jobs.job_cat_id WHERE jobs.is_active = '1' ");
while($result = mysqli_fetch_array($get_job) ) {
$job_id = (int) $result['job_id'];
$job_title = htmlspecialchars($result['job_title']);
$job_category = htmlspecialchars($result['job_cat_name']);
echo "<h4>$job_category</h4>";
echo "<p>$job_title</p>";
}
Now, It's showing me all category with all jobs but I want to show all jobs under each category.
What is showing now :
Job Category 1
1. job 1 from category 1
Job Category 1
1. Job 2 from category 1
Job Category 2
1. Job 3 from category 2
First we have to remember that the result from a SELECT query is a newly generated table. It is not a multi dimensional array. If it were a multidimensional array, then you could get away with printing the job category at the beginning of each new array which could be grouping up all the jobs in a single category, however since this is not the type of result obtained by the SQL SELECT QUERY, you are printing the job category after each line:
echo "<h4>$job_category</h4>";
echo "<p>$job_title</p>";
Solution:
A solution to your problem would be to first use the ORBER BY ASC in your sql query:
$get_job = mysqli_query($conn, "SELECT jobs.job_id, jobs.job_title, job_category.job_cat_name FROM jobs LEFT JOIN job_category ON job_category.job_cat_id = jobs.job_cat_id WHERE jobs.is_active = '1' ORDER BY job_cat_id ASC");
From there, you know that the jobs in each category should at least be grouped up next to each other (from lowest to highest like 1,1,1,1,2,2,3,3,3). What you can now do is have a conditional print the $job_category if AND ONLY IF it hasn't been printed already previously.
Change this line:
echo "<h4>$job_category</h4>";
into this line:
if ($previous_print != $job_category)
{
echo "<h4>$job_category</h4>";
$previous_print = $job_category;
}
Let me know if it works now.
Another solution may be if you just run one query using group by job_cat_id and then inside loop write another query to get desired result with where clause job_cat_id .
You need to do 2 queries here. Here's an exmaple code, might need some tweaks acording to your table column names:
<?php
$query = "SELECT `job_cat_id`, `job_cat_name`, COUNT(`jobs`.`id`) as `jobs`
FROM `job_category`
GROUP BY `job_cat_id`";
$get_cat = mysqli_query($conn, $query);
$cats = [];
while($result = mysqli_fetch_array($get_cat) ) {
$result['jobs'] = [];
$cats[$result['job_cat_id']] = $result;
}
$get_job = mysqli_query($conn, "SELECT jobs.job_id, jobs.job_title, jobs.job_cat_id FROM jobs WHERE jobs.is_active = '1' AND `job_cat_id` IN (" . implode(',', array_keys($cats)) . ")");
while($result = mysqli_fetch_array($get_job) ) {
$cats[$result['job_cat_id']][] = $result;
}
foreach ($cats as $cat) {
$job_category = htmlspecialchars($cat['job_cat_name']);
echo "<h4>$job_category</h4>";
foreach ($cat['jobs'] as $job) {
$job_title = htmlspecialchars($job['job_title']);
echo "<p>$job_title</p>";
}
}

php - mysqli count rows with specific value

At the moment I'm able to count all the record's in a table with the value "Waiting". This is done by using:
$query = "SELECT COUNT(*) AS SUM FROM jobs WHERE status='Waiting'";
When I want to echo the row count I just do:
echo $rows['SUM'];
How can I do it so it also count's all the record's in a table with the value "Ready"?
This query will return all status count divided by status:
SELECT status, COUNT(status) AS tot FROM jobs GROUP BY status
The resulting set is something like this:
status tot
----------- ------
Waiting 123
Ready 80
... 56
So you want status='Waiting' or status='Ready'? You can separate parameters with OR or AND; for example:
$query = "SELECT COUNT(*) AS SUM FROM jobs WHERE status='Waiting' OR status='Ready'";
SELECT count(status) AS 'count' FROM jobs GROUP BY status HAVING status='Ready'
This will count the records with the status = Ready. You use GROUP BY to get an aggregate on the status field. And because you have used GROUP BY, you use HAVING (which is the equivalent of WHERE in GROUP situations) to filter the data.
By using IN operator in your query.
$query = "SELECT COUNT(*) AS SUM FROM jobs WHERE status IN ('Waiting','Ready')";
Get group based(status) counts by using GROUP BY operator
$query = "SELECT COUNT(*) AS SUM FROM jobs GROUP BY status";
Print the status based result.
//Create the `mysqli_connection` and assign to `$conn` variable.
$result = mysqli_query($conn, $query);
if($result->num_rows>0)
{
while($row = mysqli_fetch_assoc($result))
{
echo "<br>status=" . $row['status'];
echo "<br>SUM=" . $row['SUM'];
}
}

PHP, SQL - getting fetch where table id = user id and count other table where row is = user id

Thanks for helping, first I will show code:
$dotaz = "Select * from customers JOIN contracts where customers.user_id ='".$_SESSION['user_id']."' and contracts.customer_contract = ".$_SESSION['user_id']." order by COUNT(contracts.customer_contract) DESC limit $limit, $pocetZaznamu ";
I need to get the lists of users (customers table) ordered by count of contracts(contracts table)
I tried to solve this by searching over there, but I can't... if you help me please and explain how it works, thank you! :) $pocetZanamu is Number of records.
I need get users (name, surname etc...) from table customers, ordered by number of contracts in contracts table, where is contract_id, customer_contract (user id)..
This should do it where is the column name you are counting.
$id = $_SESSION['user_id'] ;
$dotaz = "Select COUNT(`customer_contract`) AS CNT, `customer_contract` FROM `contracts` WHERE `user_id`=$id GROUP BY `customer_contract` ORDER BY `CNT` DESC";
Depending on what you are doing you may want to store the results in an array, then process each element in the array separately.
while ($row = mysqli_fetch_array($results, MYSQL_NUM)){
$contracts[$row[1]] = $row[0];
}
foreach ($contracts AS $customer_contract => $count){
Process each user id code here
}
Not sure what you are counting. The above counts the customer_contract for a table with multiple records containing the same value in the customer_contract column.
If you just want the total number of records with the same user_id then you'd use:
$dotaz = "Select 1 FROM `contracts` WHERE `user_id`=$id";
$results = $mysqli->query($dotaz);
$count = mysql_num_rows($results);

Loop through SQL and calculate sum in PHP

I have an issue with my code. I have 2 tables. First employee_id:
|Employee id|
1
2
3
And the second table called employee_times:
|Employee_id|Hours_dev|hours_pm|
|1|2|3|
|1|3|4|
|2|3|3|
What I am trying to do is to calculate the total time that each employee has worked (hours_dev+hours_pm). For example employee_id 1 has worked 12 hours
So far I have tried to retrieve all the employee_id from the first table and use a for loop to go through the employee_times in an SQL statement (SEE CODE BELOW). However the code does not work as it prints 0 for both employee_id and total_hours.
I am using MYSQL on a localhost server.
$sql = "SELECT employee_id FROM employee";
$result = mysql_query($sql);
while($row = mysql_fetch_array)
{
$employee_id = $row['employee_id'];
}
$employee_id_length = sizeof($employee_id);
for($i = 0; $i < $employee_id_length; $i++)
{
$sql4 = "SELECT employee_id, hours_dev, hours_pm FROM employee_times WHERE employee_id= '$employee_id[$i]'";
$result = mysql_query($sql4);
while($info = mysql_fetch_array($result));
{
$employee_id = $info['employee_id'];
$hours_dev=$info['hours_dev'];
$hours_pm=$info['hours_pm'];
$total_hours = ($total_hours + $hours_dev + $hours_pm );
}
//print "$employee_id worked for $total_hours";
}
Any help is much appreciated.
you can get sum directly
select employee_id, sum(hours_dev)+ sum(hours_pm) as total
from employee_times WHERE employee_id= '1'
group by employee_id
refer this Fiddle Demo
this should get the data you need
SELECT
hours_dev,
hours_pm,
sum(hours_dev) + sum(hours_pm) as total_hours
FROM
employee_times
WHERE
employee_id = 123
GROUP BY
employee_id
Take a look at aggregate functions:
http://www.w3schools.com/sql/sql_functions.asp
http://www.w3schools.com/sql/sql_func_sum.asp
This SQL query should pull the info much quicker than by script;
SELECT Employee_id, SUM(Hours_dev), SUM(Hours_pm), SUM(Hours_dev + Hours_pm)
FROM employee_times
GROUP BY Employee_id

Categories