How to retrieve result set from MySQL case query in PHP - php

I've been looking for an answer to this all afternoon so far and cannot come up with anything yet.
I have the following MySQL PDO query:
$q = "select recip_id,
sum(case when msg_read = '0' AND msg_deleted = '0' then 1 else 0 end) uu,
sum(case when msg_read = '0' AND msg_deleted = '1' then 1 else 0 end) ud,
sum(case when msg_read = '1' AND msg_deleted = '0' then 1 else 0 end) ru,
sum(case when msg_read = '1' AND msg_deleted = '1' then 1 else 0 end) rd,
count(*) as total
from messages where recip_id = :d GROUP BY recip_id WITH ROLLUP";`
which, when I use recip_id = 18 for an example in PHPMyAdmin gives me the following table:
I have tried several ways to fetch the resulting row in php so that I can use the values for another task, to no avail. I've tried this:
$stmt = $dbo->prepare($q);
$row = $stmt->execute(array(":id" => $id));
$total = $row['total'];
$uu = $row['uu'];
$ud = $row['ud'];
$ru = $row['ru'];
$rd = $row['rd'];
echo "Recipient id: $id, Total: $total, UU: $uu, UD: $ud, RU: $ru, RD: $rd";
And this:
$stmt = $dbo->prepare($q);
$stmt->bindParam(":id", $id);
$msgcount = array();
while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
$total = $row->total;
$uu = $row->uu;
$ud = $row->ud;
$ru = $row->ru;
$rd = $row->rd;
}
echo "Recipient id: $id, Total: $total, UU: $uu, UD: $ud, RU: $ru, RD: $rd";
and this too:
$msgcount = array();
$stmt = $dbo->prepare($q);
$stmt->bindParam(":id", $id);
while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
array_push($msgcount, array($row['uu'], $row['uu'], $row['ud'], $row['ru'], $row['rd']));
}
echo $msgcount[];
I cannot retrieve the values using my PHP script from the MySQL result set. I've tried serialize() on the rows and whole result set, I've tried to use PDO::FETCH_ASSOC and also unspecified fetch() and fetchAll(). *'ve used different combos and just get an empty result set or *I can't find an answer anywhere either. Can anyone help me with this please?

In your first attempt you forget to $stmt->fetch, and in the last two you forget $stmt->execute. Try this:
$stmt = $dbo->prepare($q);
if ( ! $stmt->execute(array(":id" => $id)) ) die("error"); // returns true or false
$row = $stmt->fetch(); // add this line!
$total = $row['total'];
$uu = $row['uu'];
$ud = $row['ud'];
$ru = $row['ru'];
$rd = $row['rd'];
echo "Recipient id: $id, Total: $total, UU: $uu, UD: $ud, RU: $ru, RD: $rd";

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 use PDO rowCount() function in foreach?

i need some help , i have simple code like count rows in php, i use PDO ,
so i check if rowCount > 0 i do job if no other job but i have it in foreach function, in first step i get true result but in other i get invalid
so i think it is function like a closeCursor() in PDO but i try and no matter . maybe i do it wrong ?
it is part of my code
public function saveClinicCalendar($post){
$daysItm = '';
$Uid = $post['Uid'];
$ClinicId = $post['ClinicId'];
$type = $post['type'];
$resChck = '';
foreach($post['objArray'] as $arr){
foreach($arr['days'] as $days){
$daysItm = $days.",".$daysItm;
}
$daysItm = substr($daysItm, 0, -1);
$dateTime = $arr['dateTime'];
$sqlChck = 'SELECT * FROM clinic_weeks WHERE dates = :dates AND Uid = :Uid AND category = :category AND Cid = :Cid AND type = :type';
$resChck = $this->db->prepare($sqlChck);
$resChck->bindValue(":dates",$dateTime);
$resChck->bindValue(":Cid",$ClinicId);
$resChck->bindValue(":type",$type);
$resChck->bindValue(":Uid",$Uid);
$resChck->bindValue(":category",$Uid);
$resChck->execute();
$co = $resChck->rowCount();
if($co > 0){
/*UPDATE*/
$sql = 'UPDATE clinic_weeks SET dates = :dates ,time = :time, Cid = :Cid, type = :type, Uid = :Uid, category = :category ';
$res = $this->db->prepare($sql);
$res->bindValue(":dates",$dateTime);
$res->bindValue(":time",$daysItm);
$res->bindValue(":Cid",$ClinicId);
$res->bindValue(":type",$type);
$res->bindValue(":Uid",$Uid);
$res->bindValue(":category",$Uid);
}else{
/*INSERT*/
$sql = 'INSERT INTO clinic_weeks (dates,time, Cid,type,Uid,category) VALUES (:dates,:time, :Cid,:type,:Uid,:category)';
$res = $this->db->prepare($sql);
$res->bindValue(":dates",$dateTime);
$res->bindValue(":time",$daysItm);
$res->bindValue(":Cid",$ClinicId);
$res->bindValue(":type",$type);
$res->bindValue(":Uid",$Uid);
$res->bindValue(":category",$Uid);
}
$res->execute();
$resChck->closeCursor();
$resChck = null;
$daysItm = '';
}
}
what i am doing wrong?
many thanks to Barmar, he suggest me a true answer.
here is a code
$sql = "INSERT INTO clinic_weeks
(`timestam`,`time`,dates,Cid,type,Uid,category)
VALUES
('$timestamp','$daysItm','$dateTime','$ClinicId','$type','$Uid','$Uid')
ON DUPLICATE KEY UPDATE `time` = '$daysItm' ";
I use there "ON DUPLICATE KEY UPDATE" and it`s work perfectly!
instead a big code top of page i make a two line of code.

PHP while loop iterates only once

Quick Question;
$sql = mysql_query("SELECT * FROM cronjobs WHERE status = 0 ");
while($cronjob = mysql_fetch_array($sql)){
if($cronjob['suid'] != $cronjob['cuid']){
//echo 'not equal<br>';
$set = 0;
$sid = $cronjob['sid'];
$suid = $cronjob['suid'];
$cuid = $cronjob['cuid'];
$set = notify($sid, $suid, $cuid);
if($set==1){
//echo 'notified<br>';
$sql = "UPDATE cronjobs SET status = '1' WHERE id='".$cronjob['id']."'";
if(mysql_query($sql)){
echo '1<br>';
$set = 0;
}
}
}
}
}
notify() will return 1 (numeric)
The problem is only one iteration of the while loop is executed even though there are more records. I don't know what's wrong here. Help me out pls.
Please change inner $sql variable name to something else..outer $sql and inner one are making conflict
$sql = mysql_query("SELECT * FROM cronjobs WHERE status = 0 ");
while($cronjob = mysql_fetch_array($sql)){
if($cronjob['suid'] != $cronjob['cuid']){
//echo 'not equal<br>';
$set = 0;
$sid = $cronjob['sid'];
$suid = $cronjob['suid'];
$cuid = $cronjob['cuid'];
$set = notify($sid, $suid, $cuid);
if($set==1){
//echo 'notified<br>';
$sql_2 = "UPDATE cronjobs SET status = '1' WHERE id='".$cronjob['id']."'";
if(mysql_query($sql_2)){
echo '1<br>';
$set = 0;
}
}
}
}
}
Just an observation:
Because you have:
$sql = mysql_query("SELECT * FROM cronjobs WHERE status = 0 ");
while($cronjob = mysql_fetch_array($sql)){
Its going to execute the Query EVERY SINGLE time it goes through the loop. If you have a 100 rows, its going to execute 100 times. If you do this instead, then it executes only once.
$sql = mysql_query("SELECT * FROM cronjobs WHERE status = 0 ");
$res = mysql_fetch_array($sql);
while($cronjob = $res){
It wouldnt have conflicted either!
It is clearly an issue that occurs when you have the same variable for query ($query)
and Result Object ($result).try different name for mysql_query() inside the WHILE Loop.

mysql statement not working

I have this code
if(!isset($_GET['album_id'])) { die("Album Not Found!"); } else { $album_id = mysql_real_escape_string($_GET['album_id']); }
$sql = "SELECT * FROM `audio_albums` WHERE `album_id` = ".$album_id."";
$qry = mysql_query($sql);
$num = mysql_num_rows($qry);
if($num == 1) {
// Fetch Array
$arr = mysql_fetch_array($qry);
// Assign Values
$album_name = $arr['album_name'];
$album_name_seo = $arr['album_name_seo'];
$album_id = $arr['album_id'];
// Fetch Songs
$sql2 = "SELECT audio_id,album_id,title FROM `audios` WHERE `album_id` = ".$album_id." AND `public_private` = 'public' AND `approved` = 'yes' LIMIT 0, 30 ";
$qry2 = mysql_query($sql2);
$arr2 = mysql_fetch_array($qry2);
print_r($arr2);
} else {
echo "Album Not Found!";
}
and when i execute the code, it results in this
Array
(
[0] => qCpPdBZIpkXfVIg4iUle.mp3
[audio_id] => qCpPdBZIpkXfVIg4iUle.mp3
[1] => 1
[album_id] => 1
[2] => Ambitionz Az a Ridah
[title] => Ambitionz Az a Ridah
)
Actually it fetches data of only one row but there are several rows in result. Whats wrong in the code? why isn't it working?
Well, mysql_fetch_array fetches one row. You just need to do a loop to fetch all of them, as the manual shows: http://php.net/mysql_fetch_array
while ($arr2 = mysql_fetch_array($qry2)) {
print_r($arr2);
}
You really should learn some SQL ( yes , actually learn it ), and stop using the horribly outdated mysql_* functions.
$stmt = $dbh->prepare('
SELECT
audios.audio_id AS audio_id
audio_albums.album_id AS album_id
audios.title AS title
audio_albums.album_name AS album
audio_albums.album_name_seo AS seo_album
FROM audios
LEFT JOIN audio_albums USING (album_id)
WHERE
audio_albums.album_id = :id
audios.public_private = "public" AND
audios.approved = "yes"
LIMIT 0, 30
');
$stmt->bindParam( ':id', $_GET['album_id'], PDO::PARAM_INT );
if ( $stmt->execute() )
{
var_dump( $stmt->fetchAll(PDO::FETCH_ASSOC) );
}else{
echo 'empty .. try another';
}

SQL QUERY returning all results using OR in WHERE statement

Hoping I am just missing something simple here:
$sql = "Select * FROM user_info, user_login WHERE user_login.status = '0' OR user_login.status = '2' AND user_info.uid = user_login.uid";
$db = new connection();
$results = $db->query($sql);
$user = array();
while($info = mysql_fetch_array($results))
{
$user[] = $info;
}
$total = count($user);
//TEST the amount of rows returned.
echo $total;
for ($i = 0; $i < $total; $i++)
{
//echo data;
}
just trying to pull all data that has the user_login.status field set to "0" or "2" but it shows everything thing and it shows the items marked as 2 twice.
Does anyone see my issue?
Your precedence is getting whacked because of missing parentheses:
SELECT DISTINCT *
FROM user_info, user_login
WHERE (user_login.status = '0' OR user_login.status = '2')
AND user_info.uid = user_login.uid
Without seeing the data I can't give you more than a SELECT DISTINCT with regards to the duplicate records.
Select * FROM user_info, user_login WHERE (user_login.status = '0' OR user_login.status = '2') AND user_info.uid = user_login.uid
Order of precedence :)

Categories