Can't retrieve zero values when using COUNT and GROUP together - php

I'm struggling with a MYSQL query, when using COUNT and GROUP together it's excluding any rows that have a count of 0. I understand why this is happening but can't work out how to get around it. I've read up on potential solutions presented to those with a similar problem but I cannot see the link between the two that would allow me to solve it.
Can anybody help?
$query = "SELECT id, class_date, class_id, COUNT(*) AS reserve_count
FROM bookings
WHERE booking_status='#RESERVE#'
GROUP BY class_date, class_id
ORDER BY class_date ASC, class_id ASC" ;
$result = mysqli_query($sql,$query);
while($row = mysqli_fetch_assoc($result)) {
$bookings[$row['id']] = array('class_date' => $row['class_date'], 'class_id' => $row['class_id'], 'reserve_count' => $row['reserve_count']);
}

Logically, there shouldn't be any row with zero count because booking table should only have classes that are booked.

Related

Return list of member_number count in table

Consider the following table
I need to return a list in descending order with the count of the member_nr's who is appearing the most frequent in the table where tournament = 'EPL' AND ROUND = '12'
EXAMPLE
The script should return the following results:
I thought about the problem and my logic for the problem reads like this
STEP1: GET member_nr one by one
$sql = "SELECT DISTINCT *
FROM winners
WHERE tournament='$tour' AND round='$round'";
LOOP(){ //get 1 member number
$mem_nr = ['mem_nr']; //assign mem_nr to variable
STEP2: GET the count(number of times) ^ABOVE^ member number appears in table
"$sql="SELECT *, count(member_nr) as nrWins
FROM winners
where member_nr ='$memNr' and tournament='$tournament' AND round='$round'";"
LOOP(){//get count
STEP 3: DISPLAY DATA
echo $row=['nrWins'] //Display Number Wins
echo $memNr
}//END LOOP
}//END LOOP
My Problem:
The above does not seem very efficient to me, im looking for the shortest most efficient way to return the count of member numbers in table above, any ideas / suggestions are welcomed
Try something like this:
SELECT *, COUNT(*) AS `wins`
FROM `winners`
WHERE `tournament` = '$tournament'
AND `round` = '$round'
GROUP BY `member_nr`
ORDER BY `wins` DESC
select tournament,round,member_nr,count(*)
from table
where tournament = 'EPL'
and round = 12
group by tournament,round,member_nr
order by count(*) desc

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);

PHP Calculate rank from database

I got a little problem, I've got a database, in that database are different names, id, and coins. I want to show people their rank, so your rank has to be 1 if you have the most coins, and 78172 as example when your number 78172 with coins.
I know I can do something like this:
SELECT `naam` , `coins`
FROM `gebruikers`
ORDER BY `coins` DESC
But how can I get the rank you are, in PHP :S ?
You can use a loop and a counter. The first row from MySql is going the first rank,I.e first in the list.
I presume you want something like:
1st - John Doe
2nd - Jane Doe
..
..
right?
See: http://www.if-not-true-then-false.com/2010/php-1st-2nd-3rd-4th-5th-6th-php-add-ordinal-number-suffix
Helped me a while ago.
You could use a new varariable
$i = "1";
pe care o poti folosi in structura ta foreach,while,for,repeat si o incrementezi mereu.
and you use it in structures like foreach,while,for,repeat and increment it
$i++;
this is the simplest way
No code samples above... so here it is in PHP
// Your SQL query above, with limits, in this case it starts from the 11th ranking (0 is the starting index) up to the 20th
$start = 10; // 0-based index
$page_size = 10;
$stmt = $pdo->query("SELECT `naam` , `coins` FROM `gebruikers` ORDER BY `coins` DESC LIMIT {$start}, {$page_size}");
$data = $stmt->fetchAll();
// In your template or whatever you use to output
foreach ($data as $rank => $row) {
// array index is 0-based, so add 1 and where you wanted to started to get rank
echo ($rank + 1 + $start) . ": {$row['naam']}<br />";
}
Note: I'm too lazy to put in a prepared statement, but please look it up and use prepared statements.
If you have a session table, you would pull the records from that, then use those values to get the coin values, and sort descending.
If we assume your Session table is sessions(session_id int not null auto_increment, user_id int not null, session_time,...) and we assume that only users who are logged in would have a session value, then your SQL would look something like this: (Note:I am assuming that you also have a user_id column on your gebruikers table)
SELECT g.*
FROM gebruikers as g, sessions as s WHERE s.user_id = g.user_id
ORDER BY g.coins DESC
You would then use a row iterator to loop through the results and display "1", "2", "3", etc. The short version of which would look like
//Connect to database using whatever method you like, I will assume mysql_connect()
$sql = "SELECT g.* FROM gebruikers as g, sessions as s WHERE s.user_id = g.user_id ORDER BY g.coins DESC";
$result = mysql_query($sql,$con); //Where $con is your mysql_connect() variable;
$i = 0;
while($row = mysql_fetch_assoc($result,$con)){
$row['rank'] = $i;
$i++;
//Whatever else you need to do;
}
EDIT
In messing around with a SQLFiddle found at http://sqlfiddle.com/#!2/8faa9/6
I came accross something that works there; I don't know if it will work when given in php, but I figured I would show it to you either way
SET #rank = 0; SELECT *,(#rank := #rank+1) as rank FROM something order by coins DESC
EDIT 2
This works in a php query from a file.
SELECT #rank:=#rank as rank,
g.*
FROM
(SELECT #rank:=0) as z,
gebruikers as g
ORDER BY coins DESC
If you want to get the rank of one specific user, you can do that in mysql directly by counting the number of users that have more coins that the user you want to rank:
SELECT COUNT(*)
FROM `gebruikers`
WHERE `coins` > (SELECT `coins` FROM `gebruikers` WHERE `naam` = :some_name)
(assuming a search by name)
Now the rank will be the count returned + 1.
Or you do SELECT COUNT(*) + 1 in mysql...

Best way to sum and seperate by date in MYSQL with/witout php

Hi i have such table information:
what i want to do with php with while or just in mysql, is to SUM (time_used) of the rows with status 44 until its reached row with status 55. after that it should begin from start with new summing.
first query should return 37, second 76 (keep in mind it should be universal, for unlimited occurrences of 55 status row)
i thought of a way with time/date filtering and have this:
select sum(time_used) as sumed
from timelog
where start_time > (select end_time from timelog where (status='55')
ORDER BY id DESC LIMIT 1) ORDER BY id DESC
but this works only for last combination of 44 and 55
i know i will need two way filtering( < end_time and > end_time) so it will work for all cases, but cant think of a way to do it in php
can anyone help me?
EDIT:
sqlfiddle whoever want it:
http://sqlfiddle.com/#!2/33820/2/0
There are two ways to do it: Plain SQL or PHP. If you treat thousands of rows, it may be interresting to choose between the two by testing performance.
Plain SQL
select project_id, task_id, user_id, sum(time_used) as time_used,
min(start_time) as start_time, max(end_time) as end_time, max(comment) as comment from
(select t.id, t.project_id, t.task_id, t.user_id, t.time_used,
count(t2.id) as count55, t.start_time, t.end_time, t.comment
from timelog t
left join timelog t2 on t.id>t2.id and t2.status=55 and t.task_id=t2.task_id
group by t.id) as t
group by count55;
I assume here that a task can belong to one user only
SQL and PHP
$link = mysqli_connect( ... );
$query = "select id, project_id, task_id, user_id, time_used, start_time, end_time, status
from timelog order by id";
$result = mysqli_query($link, $query);
$table = array();
$time_used = 0;
$start_sum = true;
$i = 0;
while($row = mysqli_fetch_assoc ($result)){
if($start_sum){
$table[$i] = $row;
$start_sum = false;
} else {
$table[$i]['time_used'] += $row['time_used'];
$table[$i]['end_time'] += $row['end_time'];
}
if($row['state'] == 55){
$i++;
$start_sum = true;
}
}
If two tasks can run in simultaneously, solution 1 will work, but solution 2 will need to be adapted in order to take this in account.
here is my intepretation:
http://sqlfiddle.com/#!2/33820/45
set #n=0;
select project_id, task_id, user_id,sum(time_used) from (
SELECT time_used,project_id, task_id, user_id,
#n:=if(status=55,#n+1,#n),
if(status=55,-1,#n) as grouper FROM timelog
) as t
where grouper>-1
group by grouper;
I'm neither a php nor MySQL programmer, but I can explain the logic you want to follow. You can then code it.
First, query your db and return the results to php.
Next, set two sum variables to 0.
Start looping through your query results. Increment the first sum variable until you reach the first row that has status 55. Once you do, start incrementing the second variable.
The tricky part will be to sort your query by the row number of the table. Here is a link that will help you with that part.

Get total rows count of table

I want to get all rows count in my sql.
Table's first 2 columns look like that
My function looks like that
$limit=2;
$sql = "SELECT id,COUNT(*),dt,title,content FROM news ORDER BY dt DESC LIMIT " . $limit;
$stmt = $this->db->prepare($sql);
$stmt->execute();
$stmt->bind_result($id, $total, $datetime, $title, $content);
$stmt->store_result();
$count = $stmt->num_rows;
if ($count > 0) {
while ($stmt->fetch()) {
Inside loop, I'm getting exact value of $total, but MySQL selects only 1 row - row with id number 1. (and $count is 1 too)
Tried this sql
SELECT id,dt,title,content FROM news ORDER BY dt DESC LIMIT 2
All goes well.
Why in first case it selects only 1 row? How can I fix this issue?
for ex my table has 5 rows. I want to get 2 of them with all fields, and get all rows count (5 in this case) by one query.
Remove COUNT(*). You will only ever get 1 row if you leave it in there.
Try adding GROUP BY dt if you want to use COUNT(*) (not sure why you're using it though).
EDIT
Fine, if you insist on doing it in a single call, here:
$sql = "SELECT id,(SELECT COUNT(id) FROM news) as total,dt,title,content FROM news ORDER BY dt DESC LIMIT " . $limit;
This is likely cause by the variable $limit being set to 1, or not being set and mysql defaulting to 1. Try changing your first line to
$sql = "SELECT id,COUNT(*),dt,title,content FROM news ORDER BY dt DESC";
EDIT
Change to:
$sql = "SELECT SQL_CALC_FOUND_ROWS,id,dt,title,content FROM news ORDER BY dt DESC LIMIT " . $limit;
And then use a second query with
SELECT FOUND_ROWS( )
to get the number of rows that match the query
This totally wreaks of a HW problem... why else besides a professor's retarded method to add complexity to a simple problem would you not want to run two queries?
anyways.... here:
SELECT id, (SELECT COUNT(*) FROM news) AS row_count, dt, title, content FROM news ORDER BY dt DESC LIMIT

Categories