Iterate each row and get the count php mysql - php

I have a row in mysql
Uid campid type
1 100 Type1
1 100 Type1
1 200 Type1
I need to get the count of each Type1 for each campid
ie)
For campid 100 with Type1 - count = 2
For campid 200 with Type1 - count = 1
Below i am getting the total count of all campid which i dont want.
$Impressionarr = [];
$imp_qry = "select count(*) as ImpressionCount from ClicksAndImpressions where Uid = 101655 and CampaignID = 109 and Type='Impression' ;";
$impData = $this->getClicksAndImpressionsTable()->CustomQuery($imp_qry);
if($impData[0]['ImpressionCount'] != '' || $impData[0]['ImpressionCount'] !=NULL ){
$impr_update = "UPDATE ClicksAndImpressions SET ImpressionCount = ". $impData[0]['ImpressionCount'] ." where Uid = 101655 and CampaignID =109 and Type='Impression' ;";
$impqryexecute= $this->getClicksAndImpressionsTable()->CustomUpdate($impr_update);
foreach($impData as $key=>$data2)
{
$data2['ImpressionCount'];
$Impressionarr[] = $data2;
}
}else{
return array("errstr" => "success.", "success" => 0, "Campaigns" => "No Impression Counts");
}
public function CustomQuery($id) {
$sql = $id;
foreach (($this->tableGateway->getAdapter()->driver->getConnection()->execute($sql)) as $row){
$results[] = $row;
}
return $results;
}

select count(uid) as total, type from ClicksAndImpressions group by campid
try with the above query

Related

Is it possible to loop through the mysql table rows and check columns?

I have a "matrix" table with the following columns filled in.
matrix_id, user_id, position_1, position_2, position_3
1 1 1982 2251 5841
2 2 6204 0 0
3 3 0 0 0
4 4 0 0 0
I basically want to do the following.
Find a row with the lowest user_id and that has an empty position.
In the example above, that would be user_id 2 and position_2.
I update the row with a query.
I then move on to the next next empty position. Since user_id 2 still has an empty position_3, I update the row again with a query.
Since that row is complete, I move on to the next highest user_Id that has empty positions. In this case, it's user_id 3 and then user_id 4 the one after that.
I know I can do all of the above if I know what the user_id is. But assume in this case, I have no clue what the user_ids are. How would the queries look then?
Here is what I have so far.
$find_user = $db->prepare("SELECT * FROM matrix WHERE user_id > :user_id");
$find_user->bindValue(':user_id', 0);
$find_user->execute();
$result_user = $find_user->fetchAll(PDO::FETCH_ASSOC);
if(count($result_user) > 0) {
foreach($result_user as $row) {
$matrix_id = $row['matrix_id'];
$user_id = $row['user_id'];
$position_1 = $row['position_1'];
$position_2 = $row['position_2'];
$position_3 = $row['position_3'];
}
} else {
$errors[] = 'User Id not found in Matrix.';
}
$update_user = $db->prepare("UPDATE matrix SET position_2 = :position_2 WHERE user_id = :user_id");
$update_user->bindValue(':position_2', 1564;
$update_user->bindParam(':user_id', $user_id);
if($update_user->execute()) {}
This should go through all your users from smallest user_id to largest.
For each user it will check the relevant columns in order and apply a new value to the empty ones.
$new_val = 1999;
$result = $db->query("SELECT * FROM matrix ORDER BY user_id");
$users = $result->fetchAll(PDO::FETCH_ASSOC);
if(count($users) > 0) {
// prepare all the possible queries
// make use of prepare once execute many times
$stmt1 = $db->prepare("UPDATE `matrix` SET `position_1` = :pos WHERE `user_id` = :id");
$stmt2 = $db->prepare("UPDATE `matrix` SET `position_2` = :pos WHERE `user_id` = :id");
$stmt3 = $db->prepare("UPDATE `matrix` SET `position_3` = :pos WHERE `user_id` = :id");
foreach($users as $user) {
if ( $user['$position_1'] == 0 ) {
$stmt1->execute( array(':pos'=>++$new_val,':id'=>$user['user_id']) );
}
if ( $user['$position_2'] == 0 ) {
$stmt1->execute( array(':pos'=>++$new_val,':id'=>$user['user_id']) );
}
if ( $user['$position_3'] == 0 ) {
$stmt1->execute( array(':pos'=>++$new_val,':id'=>$user['user_id']) );
}
}
} else {
$errors[] = 'User Id not found in Matrix.';
}
You could reduce the rows to process by changing the query a bit to only find users with columns to fix
$result = $db->query("SELECT *
FROM matrix
WHERE position_1 = 0
OR position_2 = 0
OR position_3 = 0
ORDER BY user_id");
important thing here, is that you are working with the row, not columns
so check all the prerequisites and update the row.
$find_user = $db->prepare("SELECT * FROM matrix order by user_id asc");
$find_user->execute();
$result_user = $find_user->fetchAll(PDO::FETCH_ASSOC);
foreach($result_user as $row) {
$matrix_id = $row['matrix_id'];
$user_id = $row['user_id'];
$position_1 = $row['position_1'];
$position_2 = $row['position_2'];
$position_3 = $row['position_3'];
}
$str = ''
if (!$position_2){
$str = "position_2 = :position_2"
} else if (!$position_2 && !$position_3){
$str = "position_2 = :position_2 and position_3 = :position_3"
}
$update_user = $db->prepare("UPDATE matrix SET " . $str . " WHERE user_id = :user_id");
$update_user->bindValue(':position_2', 1564);
$update_user->bindValue(':position_3', 1564);
$update_user->bindParam(':user_id', $user_id);
if($update_user->execute()) {}
Also, get all the rows in the matrix table ordered by used_id and process every row, depending on your condition.

How to calculate a percentage for all student that are present

There are two tables that are going to work together.
1st Table:
AttendanceID TeacherID BatchID SubjectID SemesterID Date
32 110 8 9 1 2016-08-04
31 102 8 10 1 2016-07-17
30 108 6 22 3 2016-06-27
29 109 7 18 2 2016-06-27
28 109 8 13 1 2016-06-27
27 110 7 7 2 2016-06-27
26 110 8 9 1 2016-06-27
25 104 2 42 7 2016-04-20
24 104 5 35 5 2016-04-14
23 104 2 42 7 2016-04-14
22 102 2 41 7 2016-04-13
21 102 2 41 7 2016-04-10
20 102 6 23 3 2016-04-10
19 102 6 23 3 2016-04-10
2nd Table:
The first table is consist of unique rows which will be going to use for each new attendance list in table two.
For example: In the first table, the AttendanceID 21 is used in second table for Complete attendance of specific subject.
I want to calculate the percentage of all students in second table of a specific Subject and the total number can be get by the 1st table AttendanceID
What I did in PHP is: First I get the total number from 1st table with this query:
SELECT COUNT(AttendanceID) FROM attendances WHERE SubjectID = ? AND BatchID = ?"
Once I get the total number of attendances of specific subject and batch from first table I store it in variable $total then I write another query for getting obtained attendance from second table:
SELECT COUNT(AttendanceDetailID) FROM attendancedetail WHERE CollegeID = ? AND Status = 'present' AND SubjectID = ?"
After getting the obtained attendance I store it in variable $obtained
Once I get both values then I calculate the percentage in PHP like this:
if(!empty($total) && !empty($obtained)) {
$result = (($obtained * 100)/ $total);
$result = round($result);
}
Here is the complete code of PHP:
public function showStateOfAttendance($subjectID, $batchID){
$st = $this->conn->prepare("SELECT CollegeID, Name, Gender, Photo FROM students WHERE BatchID = ?");
$st->bind_param("i", $batchID);
$st->execute();
$st->store_result();
$num_rows = $st->num_rows;
$st->bind_result($college_id, $name, $gender, $photo);
$this->response['attendance'] = array();
while($st->fetch()) {
$this->calcultaionOfAttendance($subjectID, $college_id, $name, $gender, $photo, $batchID);
}
return json_encode($this->response);
$st->free_result();
$st->close();
}
public function calcultaionOfAttendance($subjectID, $studentID, $name, $gender, $photo, $batchID) {
$stmt = $this->conn->prepare("SELECT COUNT(AttendanceID) FROM attendances WHERE SubjectID = ? AND BatchID = ?");
$stmt->bind_param("ii", $subjectID, $batchID);
$stmt->execute();
$stmt->store_result();
$num_rows = $stmt->num_rows;
$stmt->bind_result($AttendanceID);
while($stmt->fetch()) {
$total = $AttendanceID;
}
$stmt->free_result();
$stmt->close();
$stmt2 = $this->conn->prepare("SELECT COUNT(AttendanceDetailID) FROM attendancedetail WHERE CollegeID = ? AND Status = 'present' AND SubjectID = ?");
$stmt2->bind_param("ii", $studentID, $subjectID);
$stmt2->execute();
$stmt2->store_result();
$stmt2->bind_result($AttendanceDetailID);
while($stmt2->fetch()){
$obtained = $AttendanceDetailID;
}
if(!empty($total) && !empty($obtained)) {
$result = (($obtained * 100)/ $total);
$result = round($result);
$rating = ($result)/20;
$tmp = array();
$tmp['result'] = $result;
$tmp['total'] = $total;
$tmp['obtained'] = $obtained;
$tmp['rating'] = $rating;
$tmp['name'] = $name;
$tmp['college_id'] = $studentID;
$tmp['gender'] = $gender;
$tmp['photo'] = $photo;
array_push($this->response['attendance'],$tmp);
//var_dump(array($total, $obtained, $result, $rating, $studentID, $name));
}else if(empty($total)) {
$tmp = array();
$tmp['result'] = 0.0;
$tmp['total'] = 0.0;
$tmp['obtained'] = $obtained;
$tmp['rating'] = 0.0;
$tmp['name'] = $name;
$tmp['college_id'] = $studentID;
array_push($this->response['attendance'],$tmp);
//var_dump(array("0.0",$obtained, "0.0","0.0",$studentID,$name));
}else if(empty($obtained)) {
$tmp = array();
$tmp['result'] = 0.0;
$tmp['total'] = $total;
$tmp['obtained'] = 0.0;
$tmp['rating'] = 0.0;
$tmp['name'] = $name;
$tmp['college_id'] = $studentID;
array_push($this->response['attendance'],$tmp);
//var_dump(array($total, "0.0", "0.0","0.0", $studentID , $name));
}
}
Here is the android screen shot of the queries I did: The following result is for SubjectID = 23 And BatchID = 6
It get me the required result but I need better way to calculate this, is it possible to do this with single query?
Thanks
Try:
SELECT s.CollectID, s.Name, s.Gender, s.Photo,
(SELECT count(AttendanceID) from attendances WHERE SubjectID =? and BatchID = s.BatchID) as total,
(SELECT count(AttendanceDetailID) FROM attendancedetail WHERE CollegeID = s.CollectID and Status = 'present' and SubjectID = ?) as obtained
FROM students s
WHERE s.BatchID = ?
SELECT
SUM(`Status` = 'present') AS presentCount,
COUNT(*) AS totalCount,
(SUM(`Status` = 'present') * 100) / COUNT(*) AS percent
FROM
details
WHERE
BatchID = 2
AND SubjectID = 41
AND CollegeID = 1214
GROUP BY
AttendanceID
Based on your example you don't even need to access the first table. You can just calculate it directly from the data in the second.
Put your queries in subselects:
SELECT
(SELECT COUNT(AttendanceDetailID) FROM attendancedetail WHERE CollegeID = ? AND Status = 'present' AND SubjectID = ?)
/ (SELECT COUNT(AttendanceID) FROM attendances WHERE SubjectID = ? AND BatchID = ?)
* 100
Or (more readable) join two subqueries:
SELECT (obtained * 100) / total
FROM (
SELECT COUNT(AttendanceDetailID) AS total
FROM attendancedetail
WHERE CollegeID = ? AND Status = 'present' AND SubjectID = ?
) t
CROSS JOIN (
SELECT COUNT(AttendanceID) AS obtained
FROM attendances
WHERE SubjectID = ? AND BatchID = ?
) a

Fetch the row of next in rank to the “rank of last id”?

Need help!
Mysql query:
CREATE TABLE goal_implement( id INT, percent INT );
INSERT INTO goal_implement VALUES
(1,10),
(2,15),
(3,20),
(4,40),
(5,50),
(6,20);
My PHP code - this code display the result table below....
<?php
$query2 = "SELECT _id, percent, FIND_IN_SET( percent, (
SELECT GROUP_CONCAT( percent
ORDER BY percent DESC )
FROM goal_implement )
) AS rank
FROM goal_implement
ORDER BY id DESC
";
I want this block to be on focus for the comment: I need the php code; NOT mysql query...
$result2 = mysql_query($query2, $connection);
if($result2 === FALSE) {
die(mysql_error());
}
while($row = mysql_fetch_array($result2))
{
echo
"<tr>
<td>{$row['id']}</td>
<td>{$row['percent']}</td>
<td> {$row['rank']} </td>
</tr>\n";
}
?>
Result:
id percent rank
6 20 3
5 50 1
4 40 2
3 20 3
2 15 5
1 10 6
I don't know how to fetch the row(rank) that is next on the last id for example: last id's rank is 3!I want the result Below.....
Desired result using PHP:
4 40 2
Try this:
<?php
$result2 = mysql_query($query2, $connection);
if($result2 === FALSE) {
die(mysql_error());
}
// store rows by rank
// also get the last_id_rank from the first row
$by_ranks = array();
$last_id_rank = FALSE;
while($row = mysql_fetch_array($result2)) {
$by_ranks[$row['rank']][] = $row;
if ($last_id_rank === FALSE) {
$last_id_rank = $row['rank'];
}
}
// get the results
$get_results = function($by_ranks, $last_id_rank) {
// get a sorted array of that's smaller than $last_id_rank
$ranks = array_filter(array_keys($by_ranks), function($var) use($last_id_rank) {
return $var < $last_id_rank;
});
rsort($ranks); // sort ranks by descending order
// get the rank that is just smaller than $last_id_rank
if (sizeof($ranks) == 0) {
return array();
} else {
return $by_ranks[$ranks[0]];
}
};
$results = $get_results($by_ranks, $last_id_rank);
// display results
foreach ($results as $row) {
echo "<tr>
<td>{$row['id']}</td>
<td>{$row['percent']}</td>
<td> {$row['rank']} </td>
</tr>\n";
}
?>
Since you are using mysql_fetch_array(), why don't you use it's index?
$row['rank'][$incrementHere]
I thing we can filter data with HAVING clause
$query="SELECT id, percent, FIND_IN_SET( percent, (
SELECT GROUP_CONCAT( percent
ORDER BY percent DESC )
FROM goal_implement )
) AS rank
FROM goal_implement
HAVING id >".$last_id_rank."
ORDER BY id ASC limit 1";

Group By 2 Columns with similar info to link with a 2nd table

I have two columns with similar info:
column 1 = item 1, item 3, item 5
column 3 = item 3, item 5, item 8
I want to display how many of each item are in total from both columns.
I have this:
$sql = mysql_query("SELECT FirstTypeID, SecondTypeID, ThirdTypeID, DesignID, COUNT(DesignID) FROM designs WHERE Approved = '1' GROUP BY FirstTypeID, SecondTypeID, ThirdTypeID");
while ($row = mysql_fetch_array($sql)) {
$DesignID = stripslashes($row['DesignID']);
$FirstTypeID = stripslashes($row['FirstTypeID']);
$SecondTypeID = stripslashes($row['SecondTypeID']);
$ThirdTypeID = stripslashes($row['ThirdTypeID']);
$Total = stripslashes($row['COUNT(DesignID)']);
}
$result2 = mysql_query("SELECT * FROM types WHERE TypeID = '$FirstTypeID' OR TypeID = '$SecondTypeID' OR TypeID = '$ThirdTypeID'");
while ($row2 = mysql_fetch_array($result2)) {
echo "<li><a href='index_type.php?TypeID=".$row2{'TypeID'}."'>".$row2{'TypeName'}." (" . $Total . ")</a></li>";
}
but I'm not getting the result that I want, it's only giving me results from one column.
I'm not sure if this is what you are asking for but well here it is
$typesIDs = array(type0 => "", type1 => "", type2 => ""...);
foreach($typesID as $index=>$value){
$query = "SELECT COUNT(*) AS total FROM designs COLUMN1 = ".$index." OR COLUMN2 = ".$index;
$sql = mysql_query($query);
$row = mysql_fetch_array($sql);
array[$index] => $row["total"]
}

Rank points based off the highest number in a row

I have a table called "member_points", which is set up like this:
|----|-------|----------|------------------------|
| id | uid | points | last_loggedin |
|----|-------|----------|------------------------|
| 1 | 1 | 5075 | 2012-08-02 02:04:00 |
|----|-------|----------|------------------------|
| 2 | 2 | 2026 | 2012-08-04 02:15:02 |
|----|-------|----------|------------------------|
I have a function below. I want the function to echo or return the rank like "Ranked #1" or "Ranked #2", based on the number in the row "points".
function getTopRanks($id) {
$sql = "SELECT MAX(points) AS toppoints FROM member_points";
$r = mysql_query($sql);
if ( $r !== false && mysql_num_rows($r) > 0 ) {
while ( $a = mysql_fetch_assoc($r) ) {
$points = stripslashes($a['toppoints']);
return ''.$points.'';
}
}
}
Can someone help me make this possible?
I think you are going to ranking user on the basis of points.
For such type of problem, i suggest you to first rank user on DESC order. Then pickup desire value form row.
function getTopRanks($id) {
$sql = "SELECT uid FROM member_points ORDER BY points DESC ";
$r = mysql_query($sql);
if ( $r !== false && mysql_num_rows($r) > 0 ) {
while ( $a = mysql_fetch_assoc($r) ) {
$points = stripslashes($a['toppoints']);
return ''.$points.'';
}
}
}
this will solve your problem.:)
UPDATE AS YOUR REQUIREMENTS:
function getTopRanksUser($id) {
$userPos ="Ranked position is:";
$count = 0;
$sql = "SELECT uid FROM member_points ORDER BY points DESC ";
$r = mysql_query($sql);
if ( $r !== false && mysql_num_rows($r) > 0 ) {
while ( $a = mysql_fetch_assoc($r) ) {
$count = $count+1;
$userPosCount = $userPos+$count;
return $userPosCount;
}
}
}
there should be return userPos+count. because count is increases up number of rows in table and the string ranked position is always remains same.
this will give result. Your can change return string according to your requirements. :)
thanks.
In your mysql query use ORDER BY (http://dev.mysql.com/doc/refman/5.0/en/sorting-rows.html)
so your query would become
SELECT points FROM member_points ORDER BY points DESC
this will sort the results from the query by the amount of points. (DESC will make them descending and ASC will make the result ascending).
Here's what I use for my rankings ... this code also takes into account ties and displays correctly. Just change "username" and "points" to your appropriate column names in your db and set the db connection vars: $hostName $databaseNanme $username and $password for you connection.
Hope this helps!
$sql1 = "SET #rnk=0; SET #rank=0; SET #scount=0;";
$sql2 = "SELECT username, points, rank FROM
(
SELECT AA.*,BB.username, points
(#rnk:=#rnk+1) rnk,
(#rank:=IF(#scount=points,#rank,#rnk)) rank,
(#scount:=points) newscount
FROM
(
SELECT * FROM
(SELECT COUNT(1) scorecount,points
FROM users GROUP BY points
) AAA
ORDER BY points DESC
) AA LEFT JOIN users BB USING (points)) A;";
try {
$conn = new PDO('mysql:host='.$hostName.';dbname='.$databaseName, $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->query($sql1);
$data = $conn->query($sql2);
$standings = $data->fetchAll(PDO::FETCH_ASSOC);
} catch(PDOException $e) {
error_log( 'ERROR: ' . $e->getMessage() );
}
print_r($standings);

Categories